make_mesh_3 with features: initial points for C3T3

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

make_mesh_3 with features: initial points for C3T3

Bryn Lloyd
Dear CGAL/Mesh_3 users and developers

I have an implicit domain oracle (derived from Labeled_mesh_domain_3)
with 1D features.
When I add features to my domain, make_mesh_3 sometimes does not
discover my domain at all. Without the features the domain is discovered
(usually).


Digging into the code of make_mesh_3 I noticed the strategy to add
initial points seems very different for a mesh with features
(init_c3t3_with_features) compared to one without features (init_c3t3).
This is how I understand it:

No features:
  - segments between random points on sphere and "center" are
intersected with domain - intersection points are added to C3T3

With features:
    - features (0D,1D) are sampled and points added to C3T3 with
"protecting balls"

Conclusions:
- So it seems the code for domains with features might oversee (partial)
regions with no features.
- Also, I guess, if a point on a feature is considered "outside" by the
oracle, instead of on a surface patch, regions/domains will be missed.


How to solve this?
- Would it make sense to run the initialization code to add feature
points and the add my own internal (dimension=3) points?
- How should I add these points? Can I add the points via
C3T3::insert(Point), or should I add them via the
C3T3::insert(Weighted_point)
- What weight/ball radius should I use? I don't really want to enforce
these points, but want to help the oracle discover the domains.

Thanks for any suggestions/help
Bryn






--
You are currently subscribed to cgal-discuss.
To unsubscribe or access the archives, go to
https://sympa.inria.fr/sympa/info/cgal-discuss


Reply | Threaded
Open this post in threaded view
|

Re: make_mesh_3 with features: initial points for C3T3

Benjamin Kehlet
Bryn,

I had a similar experience (see my question here: http://cgal-discuss.949826.n4.nabble.com/Unexpected-result-when-meshing-polyhedron-td4659563.html ). This was a polyhedral domain with several disconnected parts so I don't know if thisis relevant for you, though.

I ended up reimplementing Construct_initial_points to ensure that all the different parts of the domain are sufficiently represented in the set of initial points.

template< typename IGT_ >
class Polyhedral_multicomponent_mesh_domain_with_features_3
  : public CGAL::Polyhedral_mesh_domain_with_features_3< IGT_ >
{
 public:

  [...]

  struct Construct_initial_points
  {
    Construct_initial_points(const Polyhedral_multicomponent_mesh_domain_with_features_3& domain,
                             double edge_size)
     : r_domain_(domain), edge_size(edge_size) {}

    template<class OutputIterator>
    OutputIterator operator()(OutputIterator pts, const int n = 8) const;

   private:
    const Polyhedral_multicomponent_mesh_domain_with_features_3& r_domain_;
    const double edge_size;
  };

  Construct_initial_points construct_initial_points_object() const
  {
    return Construct_initial_points(*this, edge_size);
  }

  [...]
};


Best regards

Benjamin Kehlet

On 1 September 2015 at 10:26, Bryn Lloyd <[hidden email]> wrote:
Dear CGAL/Mesh_3 users and developers

I have an implicit domain oracle (derived from Labeled_mesh_domain_3) with 1D features.
When I add features to my domain, make_mesh_3 sometimes does not discover my domain at all. Without the features the domain is discovered (usually).


Digging into the code of make_mesh_3 I noticed the strategy to add initial points seems very different for a mesh with features (init_c3t3_with_features) compared to one without features (init_c3t3).
This is how I understand it:

No features:
 - segments between random points on sphere and "center" are intersected with domain - intersection points are added to C3T3

With features:
   - features (0D,1D) are sampled and points added to C3T3 with "protecting balls"

Conclusions:
- So it seems the code for domains with features might oversee (partial) regions with no features.
- Also, I guess, if a point on a feature is considered "outside" by the oracle, instead of on a surface patch, regions/domains will be missed.


How to solve this?
- Would it make sense to run the initialization code to add feature points and the add my own internal (dimension=3) points?
- How should I add these points? Can I add the points via C3T3::insert(Point), or should I add them via the C3T3::insert(Weighted_point)
- What weight/ball radius should I use? I don't really want to enforce these points, but want to help the oracle discover the domains.

Thanks for any suggestions/help
Bryn






--
You are currently subscribed to cgal-discuss.
To unsubscribe or access the archives, go to
https://sympa.inria.fr/sympa/info/cgal-discuss



Reply | Threaded
Open this post in threaded view
|

Re: make_mesh_3 with features: initial points for C3T3

Bryn Lloyd
Hi Benjamin

Thanks for the link and the suggestion. As you wrote, construct_initial_points is not called in make_mesh_3 sometimes (when there are features). Therefore, I guess it comes down to implementing my own initialization code, which either adds the points itself, or calls the 'construct_initial_points' function.

My question: Should I add "unweighted" points or is there a meaningful weight I could add to these (non-feature) points?

@CGAL developers: it would be great if the two code paths (with/without features) would both use the 'Construct_initial_points' helper.

Thanks, Bryn




On 9/1/2015 10:45 AM, Benjamin Kehlet wrote:
Bryn,

I had a similar experience (see my question here: http://cgal-discuss.949826.n4.nabble.com/Unexpected-result-when-meshing-polyhedron-td4659563.html ). This was a polyhedral domain with several disconnected parts so I don't know if thisis relevant for you, though.

I ended up reimplementing Construct_initial_points to ensure that all the different parts of the domain are sufficiently represented in the set of initial points.

template< typename IGT_ >
class Polyhedral_multicomponent_mesh_domain_with_features_3
  : public CGAL::Polyhedral_mesh_domain_with_features_3< IGT_ >
{
 public:

  [...]

  struct Construct_initial_points
  {
    Construct_initial_points(const Polyhedral_multicomponent_mesh_domain_with_features_3& domain,
                             double edge_size)
     : r_domain_(domain), edge_size(edge_size) {}

    template<class OutputIterator>
    OutputIterator operator()(OutputIterator pts, const int n = 8) const;

   private:
    const Polyhedral_multicomponent_mesh_domain_with_features_3& r_domain_;
    const double edge_size;
  };

  Construct_initial_points construct_initial_points_object() const
  {
    return Construct_initial_points(*this, edge_size);
  }

  [...]
};


Best regards

Benjamin Kehlet

On 1 September 2015 at 10:26, Bryn Lloyd <[hidden email]> wrote:
Dear CGAL/Mesh_3 users and developers

I have an implicit domain oracle (derived from Labeled_mesh_domain_3) with 1D features.
When I add features to my domain, make_mesh_3 sometimes does not discover my domain at all. Without the features the domain is discovered (usually).


Digging into the code of make_mesh_3 I noticed the strategy to add initial points seems very different for a mesh with features (init_c3t3_with_features) compared to one without features (init_c3t3).
This is how I understand it:

No features:
 - segments between random points on sphere and "center" are intersected with domain - intersection points are added to C3T3

With features:
   - features (0D,1D) are sampled and points added to C3T3 with "protecting balls"

Conclusions:
- So it seems the code for domains with features might oversee (partial) regions with no features.
- Also, I guess, if a point on a feature is considered "outside" by the oracle, instead of on a surface patch, regions/domains will be missed.


How to solve this?
- Would it make sense to run the initialization code to add feature points and the add my own internal (dimension=3) points?
- How should I add these points? Can I add the points via C3T3::insert(Point), or should I add them via the C3T3::insert(Weighted_point)
- What weight/ball radius should I use? I don't really want to enforce these points, but want to help the oracle discover the domains.

Thanks for any suggestions/help
Bryn






--
You are currently subscribed to cgal-discuss.
To unsubscribe or access the archives, go to
https://sympa.inria.fr/sympa/info/cgal-discuss




Reply | Threaded
Open this post in threaded view
|

Re: make_mesh_3 with features: initial points for C3T3

Laurent Rineau (CGAL/GeometryFactory)
In reply to this post by Bryn Lloyd
Le Tuesday 01 September 2015 10:26:56 Bryn Lloyd a écrit :

> Dear CGAL/Mesh_3 users and developers
>
> I have an implicit domain oracle (derived from Labeled_mesh_domain_3)
> with 1D features.
> When I add features to my domain, make_mesh_3 sometimes does not
> discover my domain at all. Without the features the domain is discovered
> (usually).
>
>
> Digging into the code of make_mesh_3 I noticed the strategy to add
> initial points seems very different for a mesh with features
> (init_c3t3_with_features) compared to one without features (init_c3t3).
> This is how I understand it:
>
> No features:
>   - segments between random points on sphere and "center" are
> intersected with domain - intersection points are added to C3T3
>
> With features:
>     - features (0D,1D) are sampled and points added to C3T3 with
> "protecting balls"
>
> Conclusions:
> - So it seems the code for domains with features might oversee (partial)
> regions with no features.
> - Also, I guess, if a point on a feature is considered "outside" by the
> oracle, instead of on a surface patch, regions/domains will be missed.

I agree that this code path is surprising.

The issue is that the points returned by the functor Construct_initial_points
might be in the set of protecting balls of features, or close to that set.
 
> How to solve this?
> - Would it make sense to run the initialization code to add feature
> points and the add my own internal (dimension=3) points?
> - How should I add these points? Can I add the points via
> C3T3::insert(Point), or should I add them via the
> C3T3::insert(Weighted_point)
> - What weight/ball radius should I use? I don't really want to enforce
> these points, but want to help the oracle discover the domains.


Instead of:

C3t3 c3t3 = CGAL::make_mesh_3, can you undocumented functions:


    C3t3 c3t3;
    CGAL::internal::Mesh_3::init_c3t3_with_features(c3t3,domain,criteria);
 
Then here if you want to insert your own initial points *on the boundary of
the domain*, you can use:

    typedef C3t3::Triangulation::Point Weighted_point;
    const Weighted_point p(Weighted_point::Point(x, y, z));
    Tr::Vertex_handle vh = c3t3.triangulation().insert(p);
    c3t3.set_dimension(vh, 2);

If the points you insert are on 1D features, the `set_dimension` call should
specify 1 instead of 2.

Then you can call `refine_mesh_3` as usual:

    CGAL::refine_mesh_3<C3t3>(c3t3, domain, criteria);


I am willing to improve the API of Mesh_3, to allow custom initialization of
the triangulation. What do you think could be a good API?

--
Laurent Rineau, PhD
R&D Engineer at GeometryFactory           http://www.geometryfactory.com/
Release Manager of the CGAL Project       http://www.cgal.org/


--
You are currently subscribed to cgal-discuss.
To unsubscribe or access the archives, go to
https://sympa.inria.fr/sympa/info/cgal-discuss


Reply | Threaded
Open this post in threaded view
|

Re: make_mesh_3 with features: initial points for C3T3

Bryn Lloyd
Hi Laurent


Thanks for your example code and suggestions.

I have now implemented the "sampling" by adding points inside the domain
(i.e. dimension=3) and it seems to work.
Would it be better to add intersection points on the surface (dim=2)?


Regarding the API, I could image a slight change to the
Construct_initial_points helper struct, which might allow to add
non-conflicting points.
If the struct would receive a "filter" predicate function to avoid
adding nearby points, we could modify "init_c3t3" to something like this:

   Initial_points_vector initial_points;
   domain.construct_initial_points_object( Filter(c3t3)
)(std::back_inserter(initial_points));

where Filter could be something like:

struct Filter
{
Filter(const C3t3& c3t3);
bool operator()(const Point& p) const;
};

Then init_c3t3 could be called after adding the "feature points".


Bryn





On 9/1/2015 4:09 PM, Laurent Rineau (CGAL/GeometryFactory) wrote:

> Le Tuesday 01 September 2015 10:26:56 Bryn Lloyd a écrit :
>> Dear CGAL/Mesh_3 users and developers
>>
>> I have an implicit domain oracle (derived from Labeled_mesh_domain_3)
>> with 1D features.
>> When I add features to my domain, make_mesh_3 sometimes does not
>> discover my domain at all. Without the features the domain is discovered
>> (usually).
>>
>>
>> Digging into the code of make_mesh_3 I noticed the strategy to add
>> initial points seems very different for a mesh with features
>> (init_c3t3_with_features) compared to one without features (init_c3t3).
>> This is how I understand it:
>>
>> No features:
>>    - segments between random points on sphere and "center" are
>> intersected with domain - intersection points are added to C3T3
>>
>> With features:
>>      - features (0D,1D) are sampled and points added to C3T3 with
>> "protecting balls"
>>
>> Conclusions:
>> - So it seems the code for domains with features might oversee (partial)
>> regions with no features.
>> - Also, I guess, if a point on a feature is considered "outside" by the
>> oracle, instead of on a surface patch, regions/domains will be missed.
> I agree that this code path is surprising.
>
> The issue is that the points returned by the functor Construct_initial_points
> might be in the set of protecting balls of features, or close to that set.
>  
>> How to solve this?
>> - Would it make sense to run the initialization code to add feature
>> points and the add my own internal (dimension=3) points?
>> - How should I add these points? Can I add the points via
>> C3T3::insert(Point), or should I add them via the
>> C3T3::insert(Weighted_point)
>> - What weight/ball radius should I use? I don't really want to enforce
>> these points, but want to help the oracle discover the domains.
>
> Instead of:
>
> C3t3 c3t3 = CGAL::make_mesh_3, can you undocumented functions:
>
>
>      C3t3 c3t3;
>      CGAL::internal::Mesh_3::init_c3t3_with_features(c3t3,domain,criteria);
>    
> Then here if you want to insert your own initial points *on the boundary of
> the domain*, you can use:
>
>      typedef C3t3::Triangulation::Point Weighted_point;
>      const Weighted_point p(Weighted_point::Point(x, y, z));
>      Tr::Vertex_handle vh = c3t3.triangulation().insert(p);
>      c3t3.set_dimension(vh, 2);
>
> If the points you insert are on 1D features, the `set_dimension` call should
> specify 1 instead of 2.
>
> Then you can call `refine_mesh_3` as usual:
>
>      CGAL::refine_mesh_3<C3t3>(c3t3, domain, criteria);
>
>
> I am willing to improve the API of Mesh_3, to allow custom initialization of
> the triangulation. What do you think could be a good API?
>


--
You are currently subscribed to cgal-discuss.
To unsubscribe or access the archives, go to
https://sympa.inria.fr/sympa/info/cgal-discuss