1 /*---------------------------------------------------------------------------*\
2 * OpenSG NURBS Library *
5 * Copyright (C) 2001-2006 by the University of Bonn, Computer Graphics Group*
7 * http://cg.cs.uni-bonn.de/ *
9 * contact: edhellon@cs.uni-bonn.de, guthe@cs.uni-bonn.de, rk@cs.uni-bonn.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
38 #ifndef _OSG_PARSPACETRIMMER_H_
39 #define _OSG_PARSPACETRIMMER_H_
44 #include "OSGDrawableDef.h"
45 #include "OSGConfig.h"
49 #include "OSGBezierCurve2D.h"
50 #include "OSGDCTPMesh.h"
51 #include "OSGDirectedGraph.h"
52 #include "OSGBSplineTensorSurface.h"
57 #pragma warning( disable : 171 )
60 #define OSG_ADAPTIVE_QUAD_TREE
61 //#define OSG_FORCE_NO_T_VERTICES
62 //#define OSG_KEEP_2D_POINTS
63 #define OSG_USE_SIMPLIFIER
65 //#include "NurbsPatchSurface.h"
67 #ifdef OSG_ADAPTIVE_QUAD_TREE
68 class QuadTreeCreator
;
71 static const int ERR_NO_STARTING_FACE
= -1;
72 static const int ERR_SET_MININTERSECTION
= -2;
73 static const int ERR_DIRECTEDGE
= -3;
74 static const int ERR_STATETRANSITION_I
= -4;
75 static const int ERR_STATETRANSITION_II
= -5;
76 static const int ERR_NULL_END_NODE
= -6;
77 static const int ERR_NO_MERGECURVE_START
= -7;
78 static const int ERR_NO_MERGECURVE_END
= -8;
79 static const int ERR_DEGENERATE_BEZIER
= -9;
81 #ifdef OSG_FORCE_NO_T_VERTICES
85 /* #ifndef OSG_CREATE_NORMAL_MAPS
88 #ifdef OSG_KEEP_2D_POINTS
94 class ParSpaceTrimmer
;
96 class OSG_DRAWABLE_DLLMAPPING ParSpaceTrimmerError
101 inline ParSpaceTrimmerError(void);
102 inline ParSpaceTrimmerError(int t
);
104 inline ~ParSpaceTrimmerError(void);
108 class OSG_DRAWABLE_DLLMAPPING TrimState
110 friend class ParSpaceTrimmer
;
123 struct SScanLineEntry
;
127 DCTPVertex
*pclFromVertex
;
128 DCTPVertex
*pclToVertex
;
129 SScanLineEdge
*ptPrev
;
130 SScanLineEdge
*ptNext
;
131 SScanLineEntry
*ptEntry
;
132 // unsigned int uiOrigNum;
136 struct SScanLineEntry
138 SScanLineEdge
*ptEdge
;
139 SScanLineEntry
*ptPrev
;
140 SScanLineEntry
*ptNext
;
143 struct SScanLineEvent
145 SScanLineEdge
*ptEdge
;
150 SScanLineEvent(void) : ptEdge(NULL
), bStart(false), clPos(), clOther() {}
154 SScanLineEvent(const SScanLineEvent
&other
);
155 void operator =(const SScanLineEvent
&rhs
);
158 struct OSG_DRAWABLE_DLLMAPPING SScanLineEventLess
160 inline bool operator() (const SScanLineEvent
*ptEvent1
,
161 const SScanLineEvent
*ptEvent2
) const;
164 typedef std::set
<SScanLineEvent
*, SScanLineEventLess
> ScanLineEventSet
;
166 #ifdef OSG_USE_SIMPLIFIER
167 struct SPolySimVertex
169 unsigned int uiIndex
;
173 double dSimplifyError
;
175 SPolySimVertex(void):
176 uiIndex(0), uiPrev(0), uiNext(0), clPos(), dSimplifyError(0.0) {}
179 struct OSG_DRAWABLE_DLLMAPPING SPolySimVertexLess
181 inline bool operator() (const SPolySimVertex
*ptVertex1
,
182 const SPolySimVertex
*ptVertex2
) const;
185 typedef std::set
<SPolySimVertex
*, SPolySimVertexLess
> SPolySimVertexSet
;
188 class OSG_DRAWABLE_DLLMAPPING ParSpaceTrimmer
192 bezier2ddequevector
*tcs
; //trimming curves
193 bezier3ddequevector
*tcs3d
; // 3d trimming curves
194 double terr
; // trimming error (used for 3d loops only!)
196 DCTPFace
*start_face
; //the face in which the curve starts (if it starts OVER_FACE)
197 DCTPEdge
*ie
; //last intersected edge
198 double ip
; //intersection parameter on bezier curve
199 std::vector
<std::vector
<DCTPVertex
*> > vcel
;
200 std::vector
<std::vector
<Vec2d
> > *pvccrd
;
201 std::vector
<std::vector
<Vec3d
> > *m_pvvclSewed
;
202 #ifdef OSG_FORCE_NO_T_VERTICES
203 /* #ifndef OSG_CREATE_NORMAL_MAPS
204 std::vector< std::vector< Vec3d > > *m_pvvclNormals;
206 #ifdef OSG_KEEP_2D_POINTS
207 unsigned int m_uiPosCnt
;
210 bool m_bDeleteVertexInfo
;
211 Vec2d m_clMin
, m_clMax
;
212 #ifdef OSG_ADAPTIVE_QUAD_TREE
213 QuadTreeCreator
*m_pclQuadTree
;
215 std::vector
<bool> *m_pvbReversed
;
216 std::vector
<bool> *m_pvbUsed
;
218 #ifdef OSG_USE_SIMPLIFIER
219 BSplineTensorSurface
*m_pclNurbs
;
222 bool isOverQuad(DCTPFace
*f
, Vec2d
&p
);
223 bool isNearQuad(DCTPFace
*f
, Vec2d
&p
);
224 bool isOverFace(DCTPFace
*f
, Vec2d
&p
);
226 void getStartingFace(Vec2d p
);
227 void initializeStartState(bezier2ddeque
& tc
);
228 void initializeStartState2(unsigned int uiLoop
, std::vector
<DCTPVertex
*> &el
);
230 void *isOnFaceBoundary(DCTPFace
*f
, Vec2d
&p
, bool &isedge
);
231 bool isOnEdge(DCTPEdge
*e
, Vec2d
&p
, DCTPVertex
* &v
);
232 bool isOnSection(Vec2d
&p1
, Vec2d
&p2
, Vec2d
&p
);
234 void processCurve(bezier2ddeque
&tc
, std::vector
<DCTPVertex
*> &el
);
235 void processCurve2(unsigned int uiLoop
, std::vector
<DCTPVertex
*> &el
);
236 bool StateTransition(BezierCurve2D
&b
, std::vector
<DCTPVertex
*> &el
);
237 #ifdef OSG_FORCE_NO_T_VERTICES
238 // #ifdef OSG_CREATE_NORMAL_MAPS
239 bool StateTransition2(Vec2d
&rclAct
, Vec2d clNext
, std::vector
<DCTPVertex
*> &el
, Vec3d
&rclActS
, Vec3d clNextS
);
241 bool StateTransition2( Vec2d &rclAct, Vec2d clNext, std::vector< DCTPVertex* > &el, Vec3d &rclActS, Vec3d clNextS, Vec3d &rclActN, Vec3d clNextN );
244 bool StateTransition2(Vec2d
&rclAct
, Vec2d clNext
, std::vector
<DCTPVertex
*> &el
, Vec3d
&rclActS
, Vec3d clNextS
);
246 bool setMinIntersectionWithFace(BezierCurve2D
&b
);
247 bool setMinIntersectionWithFace2(Vec2d clAct
, Vec2d clNext
);
248 bool goingOutOnEdge(BezierCurve2D
& bc
, DCTPVertex
*&v
, bool &feu
, std::vector
<DCTPVertex
*> &el
);
249 bool goingOutOnEdge2(Vec2d clAct
, Vec2d clNext
, DCTPVertex
*&v
, bool &feu
, std::vector
<DCTPVertex
*> &el
);
250 // bool StoreCurveToFace( BezierCurve2D &bc, double t, DCTPVertex *v );
251 bool StoreCurveApproximation(BezierCurve2D
&bc
, double t
, std::vector
<DCTPVertex
*> &el
);
252 DCTPFace
* getContinuingFace(BezierCurve2D
&bc
);
253 DCTPFace
* getContinuingFace2(Vec2d clAct
, Vec2d clNext
);
254 Vec2d
calcNormal(Vec2d
&a
, Vec2d
&b
);
255 bool checkEdgeNormals(DirectedGraph
<Vec2d
, unsigned char> &sg
, int from
, int to
);
256 void checkEdgeloops(); //check for intersections/overlappings in edgeloops and remove them
257 bool insertScanLineEvents(SScanLineEdge
*ptEdge
, ScanLineEventSet
&rsptEvents
, char cWhich
= -1); // ucWhich = -1 for both
258 SScanLineEntry
*insertInScanLine(SScanLineEntry
*ptActEntry
, SScanLineEntry
*ptScanLine
);
259 void saveLoop(SScanLineEdge
*ptEdge
);
260 void checkSLIntersection(SScanLineEntry
*ptActEntry
, ScanLineEventSet
&rsptEvents
);
261 void ScanLineIntersect(SScanLineEntry
*ptEntry1
, SScanLineEntry
*ptEntry2
, ScanLineEventSet
&rsptEvents
);
262 bool isSLEntryLess(SScanLineEdge
*ptEdge1
, SScanLineEdge
*ptEdge2
);
263 void removeSLEntry(SScanLineEntry
*ptEntry
, ScanLineEventSet
&rsptEvents
);
264 DCTPVertex
* intersectsLoop(DCTPVertex
*pclVertex1
, DCTPVertex
*pclVertex2
, unsigned int uiLoop
);
265 bool doIntersect(Vec2d clV1
, Vec2d clV2
, Vec2d clV3
, Vec2d clV4
, double &rdParam
);
266 void deleteVertexInfo();
267 bool isLoopValid(const unsigned int cuiLoop
);
268 bool intersectsRay(const Vec2d cclV1
, const Vec2d cclV2
, const Vec2d cclStart
, const Vec2d cclEnd
);
271 inline ParSpaceTrimmer(void);
272 inline ~ParSpaceTrimmer(void);
274 void Initialize(DCTPMesh
&m
, bezier2ddequevector
&c2d
, bezier3ddequevector
&c3d
, std::vector
<std::vector
<Vec2d
> > &vccrd
, double err
275 #ifdef OSG_USE_SIMPLIFIER
276 , BSplineTensorSurface
*pclNurbs
280 // std::cerr << "trim with err = " << err << std::endl;
287 #ifdef OSG_USE_SIMPLIFIER
288 m_pclNurbs
= pclNurbs
;
291 void Initialize(DCTPMesh
&m
, bezier2ddequevector
&tc
, std::vector
<std::vector
<Vec2d
> > &vccrd
292 #ifdef OSG_ADAPTIVE_QUAD_TREE
293 , QuadTreeCreator
*pclQuadTree
295 #ifdef OSG_USE_SIMPLIFIER
296 , BSplineTensorSurface
*pclNurbs
303 m_clMin
[0] = m_clMax
[0] = (*mesh
->vertices
.begin() )->coords
[0];
304 m_clMin
[1] = m_clMax
[1] = (*mesh
->vertices
.begin() )->coords
[1];
306 for(dctpvertexset::iterator it_vertex
= mesh
->vertices
.begin(); it_vertex
!= mesh
->vertices
.end(); ++it_vertex
)
308 (*it_vertex
)->vertexinfo
= reinterpret_cast<void*>(1);
309 if( (*it_vertex
)->coords
[0] < m_clMin
[0])
310 m_clMin
[0] = (*it_vertex
)->coords
[0];
311 else if( (*it_vertex
)->coords
[0] > m_clMax
[0])
312 m_clMax
[0] = (*it_vertex
)->coords
[0];
313 if( (*it_vertex
)->coords
[1] < m_clMin
[1])
314 m_clMin
[1] = (*it_vertex
)->coords
[1];
315 else if( (*it_vertex
)->coords
[1] > m_clMax
[1])
316 m_clMax
[1] = (*it_vertex
)->coords
[1];
319 m_clMin
[0] += DCTP_EPS
* 0.5;
320 m_clMin
[1] += DCTP_EPS
* 0.5;
321 m_clMax
[0] -= DCTP_EPS
* 0.5;
322 m_clMax
[1] -= DCTP_EPS
* 0.5;
323 #ifdef OSG_ADAPTIVE_QUAD_TREE
324 m_pclQuadTree
= pclQuadTree
;
326 #ifdef OSG_USE_SIMPLIFIER
327 m_pclNurbs
= pclNurbs
;
329 // m_bMaxLength = false;
333 #ifdef OSG_FORCE_NO_T_VERTICES
334 // #ifdef OSG_CREATE_NORMAL_MAPS
335 void Initialize2(DCTPMesh
&m
, std::vector
<std::vector
<Vec2d
> > &vccrd
, std::vector
<std::vector
<Vec3d
> > &vvclSewed
, std::vector
<bool> &rvbRev
, std::vector
<bool> &rvbUsed
)
337 void Initialize2( DCTPMesh &m, std::vector< std::vector< Vec2d > > &vccrd, std::vector< std::vector< Vec3d > > &vvclSewed, std::vector< std::vector< Vec3d > > &vvclNormals, std::vector< bool > &rvbRev, std::vector< bool > &rvbUsed )
340 void Initialize2(DCTPMesh
&m
, std::vector
<std::vector
<Vec2d
> > &vccrd
, std::vector
<std::vector
<Vec3d
> > &vvclSewed
, std::vector
<bool> &rvbRev
, std::vector
<bool> &rvbUsed
)
346 m_pvvclSewed
= &vvclSewed
;
347 #ifdef OSG_FORCE_NO_T_VERTICES
348 /* #ifndef OSG_CREATE_NORMAL_MAPS
349 m_pvvclNormals = &vvclNormals;
352 m_pvbReversed
= &rvbRev
;
353 m_pvbUsed
= &rvbUsed
;
354 if(mesh
->vertices
.size() )
356 m_clMin
[0] = m_clMax
[0] = (*mesh
->vertices
.begin() )->coords
[0];
357 m_clMin
[1] = m_clMax
[1] = (*mesh
->vertices
.begin() )->coords
[1];
360 for(dctpvertexset::iterator it_vertex
= mesh
->vertices
.begin(); it_vertex
!= mesh
->vertices
.end(); ++it_vertex
)
362 (*it_vertex
)->vertexinfo
= NULL
;
363 if( (*it_vertex
)->coords
[0] < m_clMin
[0])
364 m_clMin
[0] = (*it_vertex
)->coords
[0];
365 else if( (*it_vertex
)->coords
[0] > m_clMax
[0])
366 m_clMax
[0] = (*it_vertex
)->coords
[0];
367 if( (*it_vertex
)->coords
[1] < m_clMin
[1])
368 m_clMin
[1] = (*it_vertex
)->coords
[1];
369 else if( (*it_vertex
)->coords
[1] > m_clMax
[1])
370 m_clMax
[1] = (*it_vertex
)->coords
[1];
373 m_clMin
[0] += DCTP_EPS
* 0.5;
374 m_clMin
[1] += DCTP_EPS
* 0.5;
375 m_clMax
[0] -= DCTP_EPS
* 0.5;
376 m_clMax
[1] -= DCTP_EPS
* 0.5;
379 int PerformTrimming(void);
380 int PerformTrimming2(void);
381 #ifdef OSG_FORCE_NO_T_VERTICES
382 #ifdef OSG_KEEP_2D_POINTS
383 int buildSurfaceGraph(DirectedGraph
<Vec2d
, unsigned char> *pGraph
, std::vector
<Vec3d
> *pvclSewed
= NULL
, std::vector
<Vec3d
> *pvclNormals
= NULL
, std::vector
<unsigned int> *pvclIdx
= NULL
);
385 int buildSurfaceGraph(DirectedGraph
<Vec2d
, unsigned char> *pGraph
, std::vector
<Vec3d
> *pvclSewed
= NULL
, std::vector
<Vec3d
> *pvclNormals
= NULL
);
388 int buildSurfaceGraph(DirectedGraph
<Vec2d
, unsigned char> *pGraph
, std::vector
<Vec3d
> *pvclSewed
= NULL
);
389 void getTrimmingLoops(std::vector
<std::vector
<Vec2d
> > &rvvclTrimmingLoops
);
393 #ifdef OSG_USE_SIMPLIFIER
394 double DistToEdge(const Vec3d cclPoint
, const Vec3d cclLine1
, const Vec3d cclLine2
) const;
399 ParSpaceTrimmer(const ParSpaceTrimmer
&other
);
400 void operator=(const ParSpaceTrimmer
&rhs
);
404 #pragma warning( default : 171 )
409 #include "OSGParSpaceTrimmer.inl"