File: predicates.h

package info (click to toggle)
cgal 6.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 144,952 kB
  • sloc: cpp: 811,597; ansic: 208,576; sh: 493; python: 411; makefile: 286; javascript: 174
file content (199 lines) | stat: -rw-r--r-- 7,902 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
// Copyright (c) 2016 GeometryFactory (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
//
// $URL: https://github.com/CGAL/cgal/blob/v6.1.1/Polygon_mesh_processing/include/CGAL/Polygon_mesh_processing/internal/Corefinement/predicates.h $
// $Id: include/CGAL/Polygon_mesh_processing/internal/Corefinement/predicates.h 08b27d3db14 $
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s)     : Sebastien Loriot

#ifndef CGAL_POLYGON_MESH_PROCESSING_INTERNAL_COREFINEMENT_PREDICATES_H
#define CGAL_POLYGON_MESH_PROCESSING_INTERNAL_COREFINEMENT_PREDICATES_H

#include <CGAL/license/Polygon_mesh_processing/core.h>


#include <boost/graph/graph_traits.hpp>
#include <CGAL/use.h>

namespace CGAL {
namespace Polygon_mesh_processing {
namespace Corefinement {


template<class TriangleMesh, class VertexPointMap, class Node_vector>
struct Less_along_a_halfedge{
  typedef boost::graph_traits<TriangleMesh> GT;
  typedef typename GT::halfedge_descriptor halfedge_descriptor;
  halfedge_descriptor hedge;
  const TriangleMesh& tm;
  const VertexPointMap& vpm;
  const Node_vector& nodes;

  Less_along_a_halfedge(halfedge_descriptor hedge_,
                        const TriangleMesh& tm_,
                        const VertexPointMap& vpm_,
                        const Node_vector& nodes_)
    : hedge(hedge_)
    , tm(tm_)
    , vpm(vpm_)
    , nodes(nodes_)
  {}

  bool operator()(std::size_t i, std::size_t j) const {
    return CGAL::collinear_are_strictly_ordered_along_line(
      nodes.to_exact(get(vpm, target(hedge,tm))),
      nodes.exact_node(j),
      nodes.exact_node(i));
  }
};

//Considering the plane with normal vector [o_prime,o] and containing o.
//We define the counterclockwise order around o when looking from
//the side of the plane containing o_prime.
//We consider the portion of the plane defined by rotating a ray starting at o
//from the planar projection of p1 to the planar projection of p2 in
//counterclockwise order.
//The predicates indicates whether the planar projection of point q lies in this
//portion of the plane.
//Preconditions:
//  o_prime,o,p1 are not collinear
//  o_prime,o,p2 are not collinear
//  o_prime,o,q are not collinear
//  o_prime,o,p1,q are not coplanar or coplanar_orientation(o,o_prime,p1,q)==NEGATIVE
//  o_prime,o,p2,q are not coplanar or coplanar_orientation(o,o_prime,p2,q)==NEGATIVE
template <class Kernel>
bool  sorted_around_edge(
  const typename Kernel::Point_3& o_prime, const typename Kernel::Point_3& o,
  const typename Kernel::Point_3& p1, const typename Kernel::Point_3& p2,
  const typename Kernel::Point_3& q)
{
  //guarantee to have non-flat triangles
  CGAL_precondition( !collinear(o_prime,o,p1) );
  CGAL_precondition( !collinear(o_prime,o,p2) );
  CGAL_precondition( !collinear(o_prime,o,q)  );

  //no two triangles are coplanar and on the same side of their common edge
  CGAL_precondition( !coplanar(o_prime,o,p1,q)
                     || coplanar_orientation(o,o_prime,p1,q)==NEGATIVE );
  CGAL_precondition( !coplanar(o_prime,o,p2,q)
                     || coplanar_orientation(o,o_prime,p2,q)==NEGATIVE );

  typename Kernel::Orientation_3 orientation;
  const auto s0 = orientation(o_prime, o, p1, p2);

  if ( s0==COPLANAR ) {
    //o, o_prime, p1 and p2 are coplanar
    Orientation orient=orientation(o_prime,o,p1,q);
    CGAL_precondition(orient!=COPLANAR);
    return orient==POSITIVE;
  }

  //o, o_prime, p1 and p2 are not coplanar
  const auto s1 = orientation(o_prime, o, p1, q);
  const auto s2 = orientation(o_prime, o, q , p2);

  if (s0 == POSITIVE) // the angle p1,o,p2 is smaller that Pi.
    return ( s1 == POSITIVE )
           && ( s2 ==POSITIVE ); //true if the angles p1,o,q and q,o,p2 are smaller than Pi
  else
    return ( s1 != NEGATIVE )
           || ( s2 != NEGATIVE ); //true if the angle p1,o,q or the angle q,o,p2 is smaller than or equal to Pi
}

template <class Kernel>
bool  p_is_below_q(const typename Kernel::Point_3& o_prime, const typename Kernel::Point_3& o,
                   const typename Kernel::Point_3& p, const typename Kernel::Point_3& q)
{
  CGAL::Orientation res = CGAL::orientation(o_prime, o, p, q);
  CGAL_assertion(res != CGAL::COPLANAR);

  return res == CGAL::POSITIVE;
}

template <class Kernel>
bool  are_triangles_coplanar_same_side(
    const typename Kernel::Point_3& o_prime, const typename Kernel::Point_3& o,
    const typename Kernel::Point_3& P, const typename Kernel::Point_3& q)
{
  if ( CGAL::orientation(o_prime, o, P ,q) != COPLANAR )
    return false;
  Orientation cpl_orient = coplanar_orientation(o_prime, o, P, q);
  CGAL_assertion( cpl_orient != COLLINEAR );
  return cpl_orient == POSITIVE;
}


template <class Node_id, class Node_vector, class vertex_descriptor, class VPMP, class VPMQ>
bool are_triangles_coplanar_same_side(Node_id o_prime_index,
                                      Node_id o_index,
                                      Node_id p_index,
                                      Node_id q_index,
                                      vertex_descriptor p,
                                      vertex_descriptor q,
                                      const VPMP& vpm_p,
                                      const VPMQ& vpm_q,
                                      const Node_vector& nodes)
{
  const Node_id NID((std::numeric_limits<Node_id>::max)());
    return are_triangles_coplanar_same_side<typename Node_vector::Exact_kernel>(
      nodes.exact_node(o_prime_index),
      nodes.exact_node(o_index),
      p_index == NID ? nodes.to_exact(get(vpm_p,p)) : nodes.exact_node(p_index),
      q_index == NID ? nodes.to_exact(get(vpm_q,q)) : nodes.exact_node(q_index)
    );
}

template <class Node_id, class Node_vector, class vertex_descriptor, class VPMP, class VPMQ>
bool sorted_around_edge( Node_id o_prime_index,
                         Node_id o_index,
                         Node_id p1_index,
                         Node_id p2_index,
                         Node_id q_index,
                         vertex_descriptor p1,
                         vertex_descriptor p2,
                         vertex_descriptor q,
                         const VPMP& vpm_p,
                         const VPMQ& vpm_q,
                         const Node_vector& nodes)
{
  const Node_id NID((std::numeric_limits<Node_id>::max)());
  return sorted_around_edge<typename Node_vector::Exact_kernel>(
           nodes.exact_node(o_prime_index),
           nodes.exact_node(o_index),
           p1_index == NID ? nodes.to_exact(get(vpm_p,p1))
                           : nodes.exact_node(p1_index),
           p2_index == NID ? nodes.to_exact(get(vpm_p,p2))
                           : nodes.exact_node(p2_index),
           q_index  == NID ? nodes.to_exact(get(vpm_q,q))
                           : nodes.exact_node(q_index ) );
}

template <class Node_id, class Node_vector, class vertex_descriptor, class VPMP, class VPMQ>
bool p_is_below_q( Node_id o_prime_index,
                     Node_id o_index,
                     Node_id p_index,
                     Node_id q_index,
                     vertex_descriptor p,
                     vertex_descriptor q,
                     const VPMP& vpm_p,
                     const VPMQ& vpm_q,
                     const Node_vector& nodes)
{
  const Node_id NID((std::numeric_limits<Node_id>::max)());
  return p_is_below_q<typename Node_vector::Exact_kernel>(
           nodes.exact_node(o_prime_index),
           nodes.exact_node(o_index),
           p_index == NID ? nodes.to_exact(get(vpm_p,p))
                           : nodes.exact_node(p_index),
           q_index == NID ? nodes.to_exact(get(vpm_q,q))
                           : nodes.exact_node(q_index) );
}


} } } // CGAL::Polygon_mesh_processing::Corefinement

#endif // CGAL_POLYGON_MESH_PROCESSING_INTERNAL_COREFINEMENT_PREDICATES_H