CFx SDK Documentation  2022 SP0
FMSliceEngine.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2015, Open Design Alliance (the "Alliance").
3 // All rights reserved.
4 //
5 // This software and its documentation and related materials are owned by
6 // the Alliance. The software may only be incorporated into application
7 // programs owned by members of the Alliance, subject to a signed
8 // Membership Agreement and Supplemental Software License Agreement with the
9 // Alliance. The structure and organization of this software are the valuable
10 // trade secrets of the Alliance and its suppliers. The software is also
11 // protected by copyright law and international treaty provisions. Application
12 // programs incorporating this software must include the following statement
13 // with their copyright notices:
14 //
15 // This application incorporates Teigha(R) software pursuant to a license
16 // agreement with Open Design Alliance.
17 // Teigha(R) Copyright (C) 2002-2015 by Open Design Alliance.
18 // All rights reserved.
19 //
20 // By use of this software, its documentation or related materials, you
21 // acknowledge and accept the above terms.
23 #include "FMProfile3D.h"
24 #include "FMGeometry.h"
25 #include "FMGeometryDebug.h"
26 #include "Modeler/FMMdlBody.h"
27 #include "Modeler/FMMdlFace.h"
28 #include "Modeler/FMMdlEdge.h"
29 #include "Modeler/FMMdlIterators.h"
30 #include "Contours/FMEdgeGraph.h"
31 #include "Contours/FMEdgeGraph.h"
34 
35 #include "Ge/GePlane.h"
36 #include "Ge/GeLineSeg3d.h"
37 #include <UInt32Array.h>
38 #include "Si/SiSpatialIndex.h"
39 #include "Si/SiShapePlane.h"
40 #include "Ge/GeLine3d.h"
41 #include "FMDebugDraw.h"
42 //#include "../sampleapplications/TADebugTx/Debug.h"
43 
44 namespace FacetModeler
45 {
46 
47 struct SpatialFaceData : public OdSiEntity {
51  const Face* face() const { return m_pFace; }
52 
53  void detach() {
55  m_pFace = 0;
56  }
57 
58  inline void attach( Face* pFace ) {
59  m_pFace = pFace;
60  m_savedTag = pFace->tag();
61  pFace->setTag( (AecTagType)this );
62  extents( pFace, m_ext );
63  }
64 
65  static void extents( const Face* pFace, OdGeExtents3d& extents ) {
66  Edge* pEdge = pFace->edge();
67  Edge* pEnd = pEdge;
68  const OdGePoint3d& pt = pEdge->vertex()->point();
69  extents.set( pt, pt );
70  do {
71  pEdge = pEdge->next();
72  extents.addPoint( pEdge->vertex()->point() );
73  }
74  while( pEdge != pEnd );
75  }
76 
77  bool extents(OdGeExtents3d& extents) const {
78  extents = m_ext;
79  return true;
80  }
81 
82  bool contains( const OdGeExtents3d& , bool , const OdGeTol& ) const {
83  return false;
84  }
85 };
86 
87 
88 template<class TSpatFData = SpatialFaceData>
90 protected:
93 private:
94  FaceSpatialIndex& operator = (const FaceSpatialIndex& ) { return *this; }
95 public:
97  destroy( true );
98  }
99  OdSiSpatialIndex& build( const Body* pBody, double eps ) {
100  destroy();
101  OdUInt32 n = pBody->faceCount();
102  if ( n ) {
103  m_pFacesIndex = OdSiSpatialIndex::createObject( false, 0, 30, 20, eps );
104  m_spatialDataArray.resize( n );
105  TSpatFData* pSFD = m_spatialDataArray.asArrayPtr();
106  FaceIterator iter( pBody );
107  while( !iter.done() ) {
108  pSFD->attach( iter.get() );
109  m_pFacesIndex->insert( pSFD );
110  iter.next();
111  ++pSFD;
112  }
113  }
114  return *m_pFacesIndex.get();
115  }
116  void destroy( bool bRestoreFaceTags = true ) {
118  if( bRestoreFaceTags ) {
119  while( m_spatialDataArray.size() ) {
120  m_spatialDataArray.last().detach();
121  m_spatialDataArray.removeLast();
122  }
123  }
124  else {
125  m_spatialDataArray.clear();
126  }
127  }
128 
131  return *m_pFacesIndex;
132  }
133 
134  const OdSiSpatialIndex& index() const {
136  return *m_pFacesIndex;
137  }
138 
140  OdUInt32 size() const {
141  if(m_pFacesIndex.isNull())
142  return 0;
143  return m_spatialDataArray.size();
144  }
145 };
146 
148 template<class T>
149 inline static T mymax( T v1, T v2 ) {
150  return v1 > v2 ? v1 : v2;
151 }
152 
156 
157 
158 
159 //typedef OdArray<const Edge*, OdMemoryAllocator<const Edge*> > EdgeConstPtrArray;
160 
161 enum FaceState {
165  kProcessed
166 };
167 
169 {
170  bool contains( const OdGeExtents3d& , bool , const OdGeTol& ) const
171  {
172  return false;
173  }
174 
175  bool intersects( const OdGeExtents3d& extents, bool planar, const OdGeTol& tol ) const
176  {
177  return !extents.isDisjoint( m_ext, tol );
178  }
179 
182 };
184 
185 
186 template<class TSpatialFaceData = SpatialFaceData>
187 class Slicer : public SlicerBaseImpl,
188  protected OdSiVisitor
189 {
190  void visit( OdSiEntity* pEntity, bool ) {
191  TSpatialFaceData* pFaceData = static_cast<TSpatialFaceData*>( pEntity );
192 
193 #ifdef _DEBUG
194  //IDebugAssist* pAssist = CreateDebugAssistant();
195  //pAssist->DebugDrawFace( pFaceData->face(), 0 );
196 #endif
197 
198  collect_segments( pFaceData->face() );
199  }
200 public:
201  void initSlicerAndFaceIndex( const Body* pBody, FaceSpatialIndex<TSpatialFaceData>& faceSpatialIndex, double eps = OdGeTol().equalVector() ) {
202  reserveBuffers( pBody->faceCount() );
203  OdGeTol sitol = faceSpatialIndex.build( pBody, eps ).tolerance();
204  setTolerance( OdGeTol( sitol.equalPoint() / sitol.equalVector() * eps, eps ) );
205  }
206 
207  void slice( const OdGePlane& cutPlane,
208  const FaceSpatialIndex<TSpatialFaceData>& faceSpatial,
209  Profile2D* pResultIncludingBoundary,
210  Profile2D* pResultExcludingCoincidingBoundary = 0,
211  Profile2D* pResultExcludingOppositeBoundary = 0,
212  Profile2D* pResultExcludingBoundary = 0,
213  FaceConstPtrArray* pCoincidingFaces = 0,
214  FaceConstPtrArray* pOppositeFaces = 0,
215  bool bUseReverseEdgeAtMerge = false,
216  OdArray<const Edge*>* sourceEdges = 0)
217  {
219  setTolerance(OdGeTol(faceSpatial.index().tolerance().equalPoint(), 1e-5));
220  set_cut_plane( cutPlane );
221  ReserveBuffers( faceSpatial.size() );
222  faceSpatial.index().query( OdSiShapePlane( cutPlane ), *this );
223  build_results( pResultIncludingBoundary,
224  pResultExcludingCoincidingBoundary,
225  pResultExcludingOppositeBoundary,
226  pResultExcludingBoundary,
227  pCoincidingFaces, pOppositeFaces, bUseReverseEdgeAtMerge, sourceEdges );
228  // algo should not produce duplicates, but it does
229  if(pResultExcludingOppositeBoundary != NULL)
230  {
231  pResultExcludingOppositeBoundary->deleteCoincident(1.e-10);
232  }
233  }
234 };
235 
236 }
#define ODA_ASSERT(exp)
Definition: DebugStuff.h:49
tol
Definition: DimVarDefs.h:2287
#define NULL
Definition: GsProperties.h:177
unsigned int OdUInt32
OdUInt32 faceCount() const
void ReserveBuffers(size_t nFaces)
FacetModeler::Vertex * vertex() const
Edge * next() const
void setTag(FacetModeler::AecTagType nTag)
Definition: FMMdlEntity.h:136
FacetModeler::AecTagType tag() const
Definition: FMMdlEntity.h:132
Edge * edge(OdUInt32 nLoop=0) const
void destroy(bool bRestoreFaceTags=true)
OdSiSpatialIndex & index()
OdSiSpatialIndexPtr m_pFacesIndex
Definition: FMSliceEngine.h:91
OdArray< TSpatFData > & faceDataArray()
const OdSiSpatialIndex & index() const
OdArray< TSpatFData > m_spatialDataArray
Definition: FMSliceEngine.h:92
OdSiSpatialIndex & build(const Body *pBody, double eps)
Definition: FMSliceEngine.h:99
void collect_segments(const Face *pFace)
void reserveBuffers(size_t nFaces)
void setTolerance(const OdGeTol &tol)
void build_results(Profile2D *pResInclBndry, Profile2D *pResExclCoBndry, Profile2D *pResExclOpBndry, Profile2D *pResExclBndry, FaceConstPtrArray *pCoincidingFaces, FaceConstPtrArray *pOppositeFaces, bool bUseReverseEdgeAtMerge, OdArray< const Edge * > *sourceEdges=0)
void set_cut_plane(const OdGePlane &cutPlane)
void slice(const OdGePlane &cutPlane, const FaceSpatialIndex< TSpatialFaceData > &faceSpatial, Profile2D *pResultIncludingBoundary, Profile2D *pResultExcludingCoincidingBoundary=0, Profile2D *pResultExcludingOppositeBoundary=0, Profile2D *pResultExcludingBoundary=0, FaceConstPtrArray *pCoincidingFaces=0, FaceConstPtrArray *pOppositeFaces=0, bool bUseReverseEdgeAtMerge=false, OdArray< const Edge * > *sourceEdges=0)
void initSlicerAndFaceIndex(const Body *pBody, FaceSpatialIndex< TSpatialFaceData > &faceSpatialIndex, double eps=OdGeTol().equalVector())
const OdGePoint3d & point() const
bool isNull() const
Definition: BaseObjectPtr.h:70
Definition: GeTol.h:49
double equalVector() const
Definition: GeTol.h:76
double equalPoint() const
Definition: GeTol.h:68
static OdSiSpatialIndexPtr createObject(OdUInt32 flags, unsigned int initialNumEntity, unsigned int maxDepth=30, unsigned int maxCount=20, double eps=1e-10)
virtual void insert(OdSiEntity *entity)=0
virtual void query(const OdSiShape &shape, OdSiVisitor &visitor) const =0
virtual const OdGeTol & tolerance() const =0
void release()
Definition: SmartPtr.h:264
const T * get() const
Definition: SmartPtr.h:326
GLfloat GLfloat v1
Definition: gles2_ext.h:295
GLfloat GLfloat GLfloat v2
Definition: gles2_ext.h:296
OdArray< Face *, OdMemoryAllocator< Face * > > FacePtrArray
OdArray< const Face *, OdMemoryAllocator< const Face * > > FaceConstPtrArray
Definition: FMMdlBody.h:40
ptrdiff_t AecTagType
Definition: FMMdlBase.h:42
OdArray< Vertex *, OdMemoryAllocator< Vertex * > > VertexIndex
bool contains(const OdGeExtents3d &, bool, const OdGeTol &) const
bool intersects(const OdGeExtents3d &extents, bool planar, const OdGeTol &tol) const
bool extents(OdGeExtents3d &extents) const
Definition: FMSliceEngine.h:77
const Face * face() const
Definition: FMSliceEngine.h:51
bool contains(const OdGeExtents3d &, bool, const OdGeTol &) const
Definition: FMSliceEngine.h:82
static void extents(const Face *pFace, OdGeExtents3d &extents)
Definition: FMSliceEngine.h:65