1 // Created on: 1999-11-02
2 // Created by: Peter KURNEV
3 // Copyright (c) 1999-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <Adaptor2d_Curve2d.hxx>
19 #include <Adaptor3d_CurveOnSurface.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23 #include <BRepTools.hxx>
24 #include <BRepTopAdaptor_FClass2d.hxx>
25 #include <Geom2d_Circle.hxx>
26 #include <Geom2d_Curve.hxx>
27 #include <Geom2d_Ellipse.hxx>
28 #include <Geom2d_Hyperbola.hxx>
29 #include <Geom2d_Line.hxx>
30 #include <Geom2d_Parabola.hxx>
31 #include <Geom2d_TrimmedCurve.hxx>
32 #include <Geom2dAPI_ProjectPointOnCurve.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_Surface.hxx>
35 #include <Geom_TrimmedCurve.hxx>
36 #include <GeomAbs_CurveType.hxx>
37 #include <GeomAdaptor_Curve.hxx>
38 #include <GeomAdaptor_Surface.hxx>
39 #include <GeomAPI_ProjectPointOnCurve.hxx>
40 #include <GeomProjLib.hxx>
41 #include <gp_Dir.hxx>
42 #include <gp_Pnt.hxx>
43 #include <gp_Pnt2d.hxx>
44 #include <gp_Vec.hxx>
45 #include <Precision.hxx>
46 #include <ProjLib_ProjectedCurve.hxx>
47 #include <TCollection_AsciiString.hxx>
48 #include <TopExp.hxx>
49 #include <TopExp_Explorer.hxx>
50 #include <TopLoc_Location.hxx>
51 #include <TopoDS.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Face.hxx>
54 #include <TopoDS_Shape.hxx>
55 #include <TopoDS_Wire.hxx>
56 #include <TopOpeBRepBuild_CorrectFace2d.hxx>
57 #include <TopOpeBRepBuild_Tools.hxx>
58 #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState.hxx>
59 #include <TopOpeBRepDS_DataMapOfShapeState.hxx>
60 #include <TopOpeBRepDS_DataStructure.hxx>
61 #include <TopOpeBRepDS_IndexedDataMapOfShapeWithState.hxx>
62 #include <TopOpeBRepDS_ShapeWithState.hxx>
63 #include <TopOpeBRepTool_2d.hxx>
64 #include <TopOpeBRepTool_CurveTool.hxx>
65 #include <TopOpeBRepTool_ShapeClassifier.hxx>
66 #include <TopOpeBRepTool_TOOL.hxx>
67 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
68 #include <TopTools_IndexedMapOfShape.hxx>
69 #include <TopTools_MapIteratorOfMapOfShape.hxx>
70 #include <TopTools_MapOfShape.hxx>
71 #include <TopTools_SequenceOfShape.hxx>
72
73 #include <stdio.h>
74 //define parameter division number as 10*e^(-PI) = 0.43213918
75 const Standard_Real PAR_T = 0.43213918;
76
77 //=======================================================================
78 //function TopOpeBRepBuild_Tools::FindState
79 //purpose :
80 //=======================================================================
FindState(const TopoDS_Shape & aSubsh,const TopAbs_State aState,const TopAbs_ShapeEnum aSubshEnum,const TopTools_IndexedDataMapOfShapeListOfShape & aMapSubshAnc,TopTools_MapOfShape & aMapProcessedSubsh,TopOpeBRepDS_DataMapOfShapeState & aMapSS)81 void TopOpeBRepBuild_Tools::FindState (const TopoDS_Shape& aSubsh,
82 const TopAbs_State aState,
83 const TopAbs_ShapeEnum aSubshEnum,
84 const TopTools_IndexedDataMapOfShapeListOfShape& aMapSubshAnc,
85 TopTools_MapOfShape& aMapProcessedSubsh,
86 TopOpeBRepDS_DataMapOfShapeState& aMapSS)
87 {
88 Standard_Integer i, nSub;
89 const TopTools_ListOfShape& aListOfShapes=aMapSubshAnc.FindFromKey(aSubsh);
90 TopTools_ListIteratorOfListOfShape anIt(aListOfShapes);
91 for (; anIt.More(); anIt.Next()) {
92 const TopoDS_Shape& aS=anIt.Value();
93 TopTools_IndexedMapOfShape aSubshMap;
94 TopExp::MapShapes (aS, aSubshEnum, aSubshMap);
95 nSub=aSubshMap.Extent();
96 for (i=1; i<=nSub; i++) {
97 const TopoDS_Shape& aSS=aSubshMap(i);
98 if (! aMapProcessedSubsh.Contains(aSS)) {
99 aMapProcessedSubsh.Add(aSS);
100 aMapSS.Bind (aSS, aState);
101 FindState (aSS, aState, aSubshEnum, aMapSubshAnc, aMapProcessedSubsh, aMapSS);
102 }
103 }
104 }
105 }
106
107 //=======================================================================
108 //function TopOpeBRepBuild_Tools::PropagateState
109 //purpose :
110 //=======================================================================
PropagateState(const TopOpeBRepDS_DataMapOfShapeState & aSplShapesState,const TopTools_IndexedMapOfShape & aShapesToRestMap,const TopAbs_ShapeEnum aSubshEnum,const TopAbs_ShapeEnum aShapeEnum,TopOpeBRepTool_ShapeClassifier & aShapeClassifier,TopOpeBRepDS_IndexedDataMapOfShapeWithState & aMapOfShapeWithState,const TopTools_MapOfShape & anAvoidSubshMap)111 void TopOpeBRepBuild_Tools::PropagateState (const TopOpeBRepDS_DataMapOfShapeState& aSplShapesState,
112 const TopTools_IndexedMapOfShape& aShapesToRestMap,
113 const TopAbs_ShapeEnum aSubshEnum,// Vertex
114 const TopAbs_ShapeEnum aShapeEnum,//Edge
115 TopOpeBRepTool_ShapeClassifier& aShapeClassifier,
116 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState,
117 const TopTools_MapOfShape& anAvoidSubshMap)
118 {
119 Standard_Integer j, nSub, nRest;
120 TopOpeBRepDS_DataMapOfShapeState aMapSS, aMapSS1;
121
122
123 TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState anItSS (aSplShapesState);
124 for (; anItSS.More(); anItSS.Next()) {
125 const TopoDS_Shape& aShape= anItSS.Key();
126 TopAbs_State aState = anItSS.Value();
127 TopTools_IndexedMapOfShape aSubshapes;
128 TopExp::MapShapes (aShape, aSubshEnum, aSubshapes);
129 nSub=aSubshapes.Extent();
130 for (j=1; j<=nSub; j++)
131 if (!anAvoidSubshMap.Contains(aSubshapes(j))) // MSV: enforce subshapes avoidance
132 aMapSS.Bind (aSubshapes(j), aState);
133 }
134
135 aMapSS1=aMapSS;
136
137 // 1. Build the Map of ShapesAndAncestors for ShapesToRest
138 TopTools_IndexedDataMapOfShapeListOfShape aMapSubshAnc;
139 nRest=aShapesToRestMap.Extent();
140 for (j=1; j<=nRest; j++)
141 TopExp::MapShapesAndAncestors(aShapesToRestMap(j), aSubshEnum, aShapeEnum, aMapSubshAnc);
142
143 // 2. Make Map Of all subshapes aMapSS
144 TopTools_MapOfShape aProcessedSubshapes;
145 anItSS.Initialize (aMapSS1);
146 for (; anItSS.More(); anItSS.Next()) {
147 const TopoDS_Shape& aSubsh = anItSS.Key();
148 TopAbs_State aState = anItSS.Value();
149 if (aMapSubshAnc.Contains (aSubsh)) {
150 aProcessedSubshapes.Add (aSubsh);
151 FindState (aSubsh, aState, aSubshEnum, aMapSubshAnc, aProcessedSubshapes, aMapSS);
152 }
153 }
154
155 // 3. Propagate the states on ShapesToRestMap
156 TopoDS_Shape aNullShape;
157 TopTools_MapOfShape aNonPassedShapes;
158 nRest=aShapesToRestMap.Extent();
159 for (j=1; j<=nRest; j++) {
160 const TopoDS_Shape& aS=aShapesToRestMap.FindKey(j);
161 TopTools_IndexedMapOfShape aSubshMap;
162 TopExp::MapShapes (aS, aSubshEnum, aSubshMap);
163 const TopoDS_Shape& aSubsh=aSubshMap(1);
164 if (aMapSS.IsBound(aSubsh)) {
165 TopAbs_State aState=aMapSS.Find(aSubsh);
166
167 if (aState==TopAbs_ON) {
168 aState=aShapeClassifier.StateShapeReference(aS, aNullShape);
169 }
170 // Add the Rest Shape to aMapOfShapeWithState
171 TopOpeBRepDS_ShapeWithState aShapeWithState;
172 aShapeWithState.SetState (aState);
173 aShapeWithState.SetIsSplitted (Standard_False);
174 aMapOfShapeWithState.Add (aS, aShapeWithState);
175 }
176
177 else {
178 aNonPassedShapes.Add(aS);
179 }
180 }
181
182 // 4. Define the states for aNonPassedShapes
183 // (for faces themselves and for theirs Wires, Edges):
184 if (aNonPassedShapes.Extent()) {
185 // Build the Map of ShapesAndAncestors for aNonPassedShapes
186 aMapSubshAnc.Clear();
187 TopTools_MapIteratorOfMapOfShape aMapIt;
188 aMapIt.Initialize (aNonPassedShapes);
189 for (; aMapIt.More(); aMapIt.Next())
190 TopExp::MapShapesAndAncestors (aMapIt.Key(), aSubshEnum, aShapeEnum, aMapSubshAnc);
191
192 aMapSS.Clear();
193 aMapIt.Initialize (aNonPassedShapes);
194 for (; aMapIt.More(); aMapIt.Next()) {
195 // Face
196 const TopoDS_Shape& aNonPassedShape=aMapIt.Key();
197
198 if (!aMapSS.IsBound(aNonPassedShape)) {
199 TopAbs_State aState = FindStateThroughVertex (aNonPassedShape, aShapeClassifier,
200 aMapOfShapeWithState,anAvoidSubshMap);
201 aMapSS.Bind (aNonPassedShape, aState);
202
203 // First Subshape
204 TopTools_IndexedMapOfShape aTmpMap;
205 TopExp::MapShapes (aNonPassedShape, aSubshEnum, aTmpMap);
206 TopoDS_Shape aFirstSubsh;
207 for (j=1; j <= aTmpMap.Extent() && aFirstSubsh.IsNull(); j++)
208 if (!anAvoidSubshMap.Contains(aTmpMap(j)))
209 aFirstSubsh = aTmpMap(j);
210 if (aFirstSubsh.IsNull()) continue;
211 aMapSS.Bind (aFirstSubsh, aState);
212
213 // Propagation of aState for subshapes
214 TopTools_MapOfShape aMapProcessedSubsh;
215 if (aSubshEnum==TopAbs_EDGE)
216 FindState1 (aFirstSubsh, aState, aMapSubshAnc, aMapProcessedSubsh, aMapSS);
217 else // if (aSubshEnum==TopAbs_VERTEX)
218 FindState2 (aFirstSubsh, aState, aMapSubshAnc, aMapProcessedSubsh, aMapSS);
219 }
220 }
221
222 // Fill aShapeWithState
223 TopOpeBRepDS_ShapeWithState aShapeWithState;
224 aShapeWithState.SetIsSplitted (Standard_False);
225 TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeState anII(aMapSS);
226 for (; anII.More(); anII.Next()) {
227 aShapeWithState.SetState (anII.Value());
228 if (anII.Key().ShapeType() != TopAbs_VERTEX)
229 aMapOfShapeWithState.Add (anII.Key(), aShapeWithState);
230 }
231 }
232 }
233
234 //=======================================================================
235 //function : TopOpeBRepBuild_Tools::FindState2
236 //purpose :
237 //=======================================================================
FindState2(const TopoDS_Shape & aSubsh,const TopAbs_State aState,const TopTools_IndexedDataMapOfShapeListOfShape & aMapSubshAnc,TopTools_MapOfShape & aMapProcessedSubsh,TopOpeBRepDS_DataMapOfShapeState & aMapSS)238 void TopOpeBRepBuild_Tools::FindState2 (const TopoDS_Shape& aSubsh,
239 const TopAbs_State aState,
240 const TopTools_IndexedDataMapOfShapeListOfShape& aMapSubshAnc,
241 TopTools_MapOfShape& aMapProcessedSubsh,
242 TopOpeBRepDS_DataMapOfShapeState& aMapSS)
243 {
244 Standard_Integer i, nSub;
245 const TopTools_ListOfShape& aListOfShapes=aMapSubshAnc.FindFromKey(aSubsh);
246 TopTools_ListIteratorOfListOfShape anIt(aListOfShapes);
247 for (; anIt.More(); anIt.Next()) {
248 //Shape
249 const TopoDS_Shape& aShape=anIt.Value();
250 aMapSS.Bind (aShape, aState);
251
252 //Subshape
253 TopTools_IndexedMapOfShape aSubshMap;
254 TopExp::MapShapes (aShape, TopAbs_VERTEX, aSubshMap);
255 nSub=aSubshMap.Extent();
256 for (i=1; i<=nSub; i++) {
257 const TopoDS_Shape& aSS=aSubshMap(i);
258 if (! aMapProcessedSubsh.Contains(aSS)) {
259 aMapProcessedSubsh.Add(aSS);
260 aMapSS.Bind (aSS, aState);
261 FindState2 (aSS, aState, aMapSubshAnc, aMapProcessedSubsh, aMapSS);
262 }
263 }
264 }
265 }
266
267 //=======================================================================
268 //function :TopOpeBRepBuild_Tools::FindState1
269 //purpose :
270 //=======================================================================
FindState1(const TopoDS_Shape & aSubsh,const TopAbs_State aState,const TopTools_IndexedDataMapOfShapeListOfShape & aMapSubshAnc,TopTools_MapOfShape & aMapProcessedSubsh,TopOpeBRepDS_DataMapOfShapeState & aMapSS)271 void TopOpeBRepBuild_Tools::FindState1 (const TopoDS_Shape& aSubsh,
272 const TopAbs_State aState,
273 const TopTools_IndexedDataMapOfShapeListOfShape& aMapSubshAnc,
274 TopTools_MapOfShape& aMapProcessedSubsh,
275 TopOpeBRepDS_DataMapOfShapeState& aMapSS)
276 {
277 Standard_Integer i, nSub, j, nW;
278 const TopTools_ListOfShape& aListOfShapes=aMapSubshAnc.FindFromKey(aSubsh);
279 TopTools_ListIteratorOfListOfShape anIt(aListOfShapes);
280 for (; anIt.More(); anIt.Next()) {
281 //Face
282 const TopoDS_Shape& aShape=anIt.Value();
283 aMapSS.Bind (aShape, aState);
284 //Wire
285 TopTools_IndexedMapOfShape aWireMap;
286 TopExp::MapShapes (aShape, TopAbs_WIRE, aWireMap);
287 nW=aWireMap.Extent();
288 for (j=1; j<=nW; j++) aMapSS.Bind (aWireMap(j), aState);
289 //Edge
290 TopTools_IndexedMapOfShape aSubshMap;
291 TopExp::MapShapes (aShape, TopAbs_EDGE, aSubshMap);
292 nSub=aSubshMap.Extent();
293 for (i=1; i<=nSub; i++) {
294 const TopoDS_Shape& aSS=aSubshMap(i);
295 if (! aMapProcessedSubsh.Contains(aSS)) {
296 aMapProcessedSubsh.Add(aSS);
297 aMapSS.Bind (aSS, aState);
298 FindState1 (aSS, aState, aMapSubshAnc, aMapProcessedSubsh, aMapSS);
299 }
300 }
301 }
302 }
303
304 //=======================================================================
305 //function :TopOpeBRepBuild_Tools::FindStateThroughVertex
306 //purpose :
307 //=======================================================================
FindStateThroughVertex(const TopoDS_Shape & aShape,TopOpeBRepTool_ShapeClassifier & aShapeClassifier,TopOpeBRepDS_IndexedDataMapOfShapeWithState & aMapOfShapeWithState,const TopTools_MapOfShape & anAvoidSubshMap)308 TopAbs_State TopOpeBRepBuild_Tools::FindStateThroughVertex (const TopoDS_Shape& aShape,
309 TopOpeBRepTool_ShapeClassifier& aShapeClassifier,
310 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState,
311 const TopTools_MapOfShape& anAvoidSubshMap)
312 {
313 TopTools_IndexedMapOfShape aSubshMap;
314 TopExp::MapShapes (aShape, TopAbs_VERTEX, aSubshMap);
315
316 TopoDS_Shape aSubsh;
317 Standard_Integer i;
318 for (i=1; i <= aSubshMap.Extent() && aSubsh.IsNull(); i++)
319 if (!anAvoidSubshMap.Contains (aSubshMap(i)) )
320 aSubsh = aSubshMap(i);
321 if (aSubsh.IsNull()) {
322 // try an edge
323 aSubshMap.Clear();
324 TopExp::MapShapes (aShape, TopAbs_EDGE, aSubshMap);
325 for (i=1; i <= aSubshMap.Extent() && aSubsh.IsNull(); i++)
326 if (!anAvoidSubshMap.Contains (aSubshMap(i)) )
327 aSubsh = aSubshMap(i);
328 if (aSubsh.IsNull()) {
329 #ifdef OCCT_DEBUG
330 std::cout<<"FindStateThroughVertex: warning: all vertices are avoided"<<std::endl;
331 #endif
332 return TopAbs_UNKNOWN; // failure
333 }
334 }
335
336 TopoDS_Shape aNullShape;
337 TopAbs_State aState=aShapeClassifier.StateShapeReference(aSubsh, aNullShape);
338 TopOpeBRepDS_ShapeWithState aShapeWithState;
339 aShapeWithState.SetState (aState);
340 aShapeWithState.SetIsSplitted (Standard_False);
341 aMapOfShapeWithState.Add(aShape, aShapeWithState);
342 SpreadStateToChild (aShape, aState, aMapOfShapeWithState);
343 return aState;
344
345 }
346
347
348 //=======================================================================
349 //function :TopOpeBRepBuild_Tools::SpreadStateToChild
350 //purpose :
351 //=======================================================================
SpreadStateToChild(const TopoDS_Shape & aShape,const TopAbs_State aState,TopOpeBRepDS_IndexedDataMapOfShapeWithState & aMapOfShapeWithState)352 void TopOpeBRepBuild_Tools::SpreadStateToChild (const TopoDS_Shape& aShape,
353 const TopAbs_State aState,
354 TopOpeBRepDS_IndexedDataMapOfShapeWithState& aMapOfShapeWithState)
355 {
356 TopTools_IndexedMapOfShape aChildMap;
357 TopExp::MapShapes (aShape, TopAbs_FACE, aChildMap);
358 TopExp::MapShapes (aShape, TopAbs_WIRE, aChildMap);
359 TopExp::MapShapes (aShape, TopAbs_EDGE, aChildMap);
360
361 TopOpeBRepDS_ShapeWithState aShapeWithState;
362 aShapeWithState.SetState (aState);
363 aShapeWithState.SetIsSplitted (Standard_False);
364
365 Standard_Integer i, n=aChildMap.Extent();
366 for (i=1; i<=n; i++) {
367 aMapOfShapeWithState.Add(aChildMap(i), aShapeWithState);
368 }
369 }
370
371 //=======================================================================
372 //function :TopOpeBRepBuild_Tools::PropagateStateForWires
373 //purpose :
374 //=======================================================================
PropagateStateForWires(const TopTools_IndexedMapOfShape & aFacesToRestMap,TopOpeBRepDS_IndexedDataMapOfShapeWithState & aMapOfShapeWithState)375 void TopOpeBRepBuild_Tools::PropagateStateForWires(const TopTools_IndexedMapOfShape& aFacesToRestMap,
376 TopOpeBRepDS_IndexedDataMapOfShapeWithState&
377 aMapOfShapeWithState)
378 {
379 Standard_Integer i, j, nF, nW, k, nE;
380
381 nF=aFacesToRestMap.Extent();
382 for (i=1; i<=nF; i++) {
383 const TopoDS_Shape& aF=aFacesToRestMap(i);
384 if (aMapOfShapeWithState.Contains (aF)) {
385 const TopOpeBRepDS_ShapeWithState& aSWS=aMapOfShapeWithState.FindFromKey(aF);
386 TopAbs_State aSt=aSWS.State();
387
388 TopTools_IndexedMapOfShape aWireMap;
389 TopExp::MapShapes (aF, TopAbs_WIRE, aWireMap);
390 nW=aWireMap.Extent();
391 for (j=1; j<=nW; j++) {
392 const TopoDS_Shape& aW=aWireMap(j);
393 TopOpeBRepDS_ShapeWithState aWireSWS;
394 aWireSWS.SetState(aSt);
395 aWireSWS.SetIsSplitted (Standard_False);
396 aMapOfShapeWithState.Add(aW, aWireSWS);
397
398 TopTools_IndexedMapOfShape aEdgeMap;
399 TopExp::MapShapes (aW, TopAbs_EDGE, aEdgeMap);
400 nE=aEdgeMap.Extent();
401 for (k=1; k<=nE; k++) {
402 const TopoDS_Shape& aE=aEdgeMap(k);
403 if (!aMapOfShapeWithState.Contains (aE)) {
404 TopOpeBRepDS_ShapeWithState anEdgeSWS;
405 anEdgeSWS.SetState(aSt);
406 anEdgeSWS.SetIsSplitted (Standard_False);
407 aMapOfShapeWithState.Add(aE, anEdgeSWS);
408 }
409 }
410 }
411 }
412 }
413 }
414
415 //=======================================================================
416 //function :TopOpeBRepBuild_Tools:: GetNormalToFaceOnEdge
417 //purpose :
418 //=======================================================================
GetNormalToFaceOnEdge(const TopoDS_Face & aFObj,const TopoDS_Edge & anEdgeObj,gp_Vec & aNormal)419 void TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge (const TopoDS_Face& aFObj,
420 const TopoDS_Edge& anEdgeObj,
421 gp_Vec& aNormal)
422 {
423 TopoDS_Edge aEd=anEdgeObj;
424 TopoDS_Face aFS=aFObj;
425 Standard_Real f2 = 0., l2 = 0., tolpc = 0., f = 0., l = 0., par = 0.;
426 Handle(Geom2d_Curve) C2D=FC2D_CurveOnSurface(aEd,aFS,f2,l2,tolpc, Standard_True);
427
428 BRepAdaptor_Curve aCA(aEd);
429 f=aCA.FirstParameter();
430 l=aCA.LastParameter();
431 par= f*PAR_T + (1 - PAR_T)*l;
432
433 gp_Pnt2d aUV1 ;
434 C2D -> D0(par, aUV1);
435
436 gp_Pnt aP;
437 gp_Vec aTg1, aTg2;
438 BRepAdaptor_Surface aSA1(aFS);
439 aSA1.D1(aUV1.X(), aUV1.Y(), aP, aTg1, aTg2);
440 aNormal = aTg1^aTg2;
441 }
442
443 //=======================================================================
444 //function : TopOpeBRepBuild_Tools::GetNormalInNearestPoint
445 //purpose :
446 //=======================================================================
GetNormalInNearestPoint(const TopoDS_Face & F,const TopoDS_Edge & E,gp_Vec & aNormal)447 void TopOpeBRepBuild_Tools::GetNormalInNearestPoint(const TopoDS_Face& F,
448 const TopoDS_Edge& E,
449 gp_Vec& aNormal)
450 {
451 Standard_Real f2 = 0., l2 = 0., tolpc = 0., par = 0.;
452
453 gp_Vec2d aTangent;
454
455 Handle(Geom2d_Curve) C2D = FC2D_CurveOnSurface(E, F, f2, l2, tolpc, Standard_True);
456
457
458 par = f2*PAR_T + (1 - PAR_T)*l2;
459
460 gp_Pnt2d aP;
461 C2D -> D1(par, aP, aTangent);
462
463 Standard_Real Xnorm = -aTangent.Y();
464 Standard_Real Ynorm = aTangent.X();
465
466 Standard_Real step = TopOpeBRepTool_TOOL::minDUV(F); step *= 1e-2;
467
468 gp_Vec2d aPV(aP.X(), aP.Y());
469 gp_Dir2d aStepV(Xnorm, Ynorm);
470 gp_Vec2d aNorm2d = aPV + gp_Vec2d(step*aStepV);
471
472 Standard_Real newU = aNorm2d.X();
473 Standard_Real newV = aNorm2d.Y();
474 gp_Vec aTg1, aTg2;
475 gp_Pnt aP1;
476
477 BRepAdaptor_Surface BS(F);
478 BS.D1(newU, newV, aP1, aTg1, aTg2);
479
480
481 gp_Pnt2d aP2d(newU, newV);
482 BRepTopAdaptor_FClass2d FC(F, Precision::PConfusion());
483 TopAbs_State aState = FC.Perform(aP2d);
484
485 //point out of face: try to go at another direction
486 if(aState == TopAbs_OUT) {
487 aStepV.Reverse();
488 aNorm2d = aPV + gp_Vec2d(step*aStepV);
489
490 newU = aNorm2d.X();
491 newV = aNorm2d.Y();
492
493 BS.D1(newU, newV, aP1, aTg1, aTg2);
494
495 //in principle, we must check again
496 // aP2d.SetX(newU); aP2d.SetY(newV);
497 // BRepClass_FaceClassifier FC(Fex, aP2d, 1e-7);
498 // TopAbs_State aState = FC.State();
499 }
500
501 aNormal = aTg1^aTg2;
502 }
503
504
505 //=======================================================================
506 //function : TopOpeBRepBuild_Tools::GetTangentToEdgeEdge
507 //purpose :
508 //=======================================================================
GetTangentToEdgeEdge(const TopoDS_Face &,const TopoDS_Edge & anEdgeObj,const TopoDS_Edge & aOriEObj,gp_Vec & aTangent)509 Standard_Boolean TopOpeBRepBuild_Tools::GetTangentToEdgeEdge (const TopoDS_Face& ,//aFObj,
510 const TopoDS_Edge& anEdgeObj,
511 const TopoDS_Edge& aOriEObj,
512 gp_Vec& aTangent)
513 {
514
515 if (BRep_Tool::Degenerated(aOriEObj) ||
516 BRep_Tool::Degenerated(anEdgeObj)) {
517 return TopOpeBRepBuild_Tools::GetTangentToEdge (anEdgeObj, aTangent) ;
518 }
519
520 TopoDS_Edge aEd=anEdgeObj, aEOri = aOriEObj;
521
522 Standard_Real f = 0., l = 0., par = 0., parOri = 0.;
523
524 BRepAdaptor_Curve aCA(aEd);
525 BRepAdaptor_Curve aCAOri(aEOri);
526
527 f=aCA.FirstParameter();
528 l=aCA.LastParameter();
529
530 par= f*PAR_T + (1 - PAR_T)*l;
531
532 gp_Pnt aP;
533 gp_Vec aTgPiece;
534 aCA.D1(par, aP, aTgPiece);
535 aTangent = aTgPiece;
536
537 gp_Pnt aPOri;
538 gp_Vec aTgOri;
539 /////
540 Handle (Geom_Curve) GCOri=aCAOri.Curve().Curve();
541 Handle (Geom_Curve) aCopyCurve = Handle(Geom_Curve)::DownCast(GCOri -> Copy());
542
543 const TopLoc_Location& aLoc = aEOri.Location();
544 gp_Trsf aTrsf = aLoc.Transformation();
545 aCopyCurve -> Transform(aTrsf);
546
547 GeomAPI_ProjectPointOnCurve aPP(aP, aCopyCurve, aCopyCurve->FirstParameter(), aCopyCurve->LastParameter());
548 #ifdef OCCT_DEBUG
549 // gp_Pnt aNP = aPP.NearestPoint();
550 #endif
551 parOri = aPP.LowerDistanceParameter();
552
553 aCopyCurve -> D1(parOri, aPOri, aTgOri);// aPOri must be equal aNP !
554 //printf(" aNP ={%lf, %lf, %lf}\n", aNP.X(), aNP.Y(), aNP.Z());
555 //printf(" aPOri={%lf, %lf, %lf}\n", aPOri.X(), aPOri.Y(), aPOri.Z());
556 if (aEd.Orientation() == TopAbs_REVERSED)
557 aTangent.Reverse();
558
559 if(aTgOri*aTgPiece < 0.) {
560 aTangent.Reverse();
561 return Standard_True;
562 }
563 return Standard_False;
564 }
565
566
567 //=======================================================================
568 //function : TopOpeBRepBuild_Tools::GetTangentToEdge
569 //purpose :
570 //=======================================================================
GetTangentToEdge(const TopoDS_Edge & anEdgeObj,gp_Vec & aTangent)571 Standard_Boolean TopOpeBRepBuild_Tools::GetTangentToEdge (const TopoDS_Edge& anEdgeObj,
572 gp_Vec& aTangent)
573 {
574 TopoDS_Edge aEd=anEdgeObj;
575
576 Standard_Real f = 0., l = 0., par = 0.;
577
578 BRepAdaptor_Curve aCA(aEd);
579
580 f=aCA.FirstParameter();
581 l=aCA.LastParameter();
582
583 par= f*PAR_T + (1 - PAR_T)*l;
584 gp_Pnt aP;
585 aCA.D1(par, aP, aTangent);
586
587 return Standard_True;
588
589 }
590
591 //=======================================================================
592 //function : TopOpeBRepBuild_Tools::GetAdjacentFace
593 //purpose :
594 //=======================================================================
GetAdjacentFace(const TopoDS_Shape & aFaceObj,const TopoDS_Shape & anEObj,const TopTools_IndexedDataMapOfShapeListOfShape & anEdgeFaceMap,TopoDS_Shape & anAdjFaceObj)595 Standard_Boolean TopOpeBRepBuild_Tools::GetAdjacentFace (const TopoDS_Shape& aFaceObj,
596 const TopoDS_Shape& anEObj,
597 const TopTools_IndexedDataMapOfShapeListOfShape& anEdgeFaceMap,
598 TopoDS_Shape& anAdjFaceObj)
599 {
600 const TopTools_ListOfShape& aListOfAdjFaces=anEdgeFaceMap.FindFromKey(anEObj);
601 TopTools_ListIteratorOfListOfShape anIt(aListOfAdjFaces);
602 TopoDS_Shape anAdjShape;
603 for (; anIt.More(); anIt.Next()) {
604 if (anIt.Value()!=aFaceObj) {
605 anAdjShape=anIt.Value();
606 break;
607 }
608 }
609
610 if (!anAdjShape.IsNull()) {
611 anAdjFaceObj=TopoDS::Face(anAdjShape);
612 return Standard_True;
613 }
614 else {
615 return Standard_False;
616 }
617 }
618
619 //=======================================================================
620 //function : UpdatePCurves
621 //purpose :
622 //=======================================================================
UpdatePCurves(const TopoDS_Wire & aWire,const TopoDS_Face & fromFace,const TopoDS_Face & toFace)623 void TopOpeBRepBuild_Tools::UpdatePCurves(const TopoDS_Wire& aWire,
624 const TopoDS_Face& fromFace,
625 const TopoDS_Face& toFace)
626 {
627 TopExp_Explorer aExp(aWire, TopAbs_EDGE);
628
629 for(; aExp.More(); aExp.Next()) {
630 TopoDS_Shape aEdge = aExp.Current();
631 UpdateEdgeOnFace(TopoDS::Edge(aEdge), fromFace, toFace);
632 }
633 }
634
635 //=======================================================================
636 //function : UpdateEdgeOnFace
637 //purpose :
638 //=======================================================================
UpdateEdgeOnFace(const TopoDS_Edge & aEdgeToUpdate,const TopoDS_Face & fromFace,const TopoDS_Face & toFace)639 void TopOpeBRepBuild_Tools::UpdateEdgeOnFace(const TopoDS_Edge& aEdgeToUpdate,
640 const TopoDS_Face& fromFace,
641 const TopoDS_Face& toFace)
642 {
643 BRep_Builder BB;
644
645 Standard_Real tolE = BRep_Tool::Tolerance(TopoDS::Edge(aEdgeToUpdate));
646 Standard_Real f2 = 0.,l2 = 0.,tolpc = 0.;
647 Handle(Geom2d_Curve) C2D;
648
649 if(BRep_Tool::Degenerated(aEdgeToUpdate)) {
650 //we can not compute PCurve for Degenerated Edge
651 //so we take as it was on old face and after (in CorrectFace2D)
652 // we will adjust this PCurve
653 C2D = FC2D_CurveOnSurface(aEdgeToUpdate, fromFace,
654 f2, l2, tolpc, Standard_True);
655 Standard_Real tol = Max(tolE, tolpc);
656 Handle(Geom2d_Curve) C2Dn = Handle(Geom2d_Curve)::DownCast(C2D -> Copy());
657 Handle(Geom2d_TrimmedCurve) newC2D = new Geom2d_TrimmedCurve(C2Dn, f2, l2);
658 BB.UpdateEdge(aEdgeToUpdate ,newC2D, toFace , tol);
659
660 }
661 else { //not degenerated edge
662
663 if(BRep_Tool::IsClosed(aEdgeToUpdate, fromFace)) {
664 UpdateEdgeOnPeriodicalFace(aEdgeToUpdate, fromFace, toFace);
665 }
666 else {
667 C2D = FC2D_CurveOnSurface(aEdgeToUpdate, toFace , f2, l2, tolpc, Standard_True);
668 Standard_Real tol = Max(tolE,tolpc);
669 BB.UpdateEdge(aEdgeToUpdate ,C2D, toFace , tol);
670 }
671 }
672 }
673
674 //=======================================================================
675 //function : UpdateEdgeOnPeriodicalFace
676 //purpose :
677 //=======================================================================
UpdateEdgeOnPeriodicalFace(const TopoDS_Edge & aEdgeToUpdate,const TopoDS_Face & fromFace,const TopoDS_Face & toFace)678 void TopOpeBRepBuild_Tools::UpdateEdgeOnPeriodicalFace(const TopoDS_Edge& aEdgeToUpdate,
679 const TopoDS_Face& fromFace,
680 const TopoDS_Face& toFace)
681 {
682 Standard_Boolean DiffOriented = Standard_False;
683 BRep_Builder BB;
684 TopoDS_Edge newE = aEdgeToUpdate; //newE.Orientation(TopAbs_FORWARD);
685 TopoDS_Face fFace = fromFace; //fFace.Orientation(TopAbs_FORWARD);
686 TopoDS_Face tFace = toFace; //tFace.Orientation(TopAbs_FORWARD);
687 Standard_Real fc = 0., lc = 0.;
688
689 Handle(Geom2d_Curve) cc = BRep_Tool::CurveOnSurface(newE, tFace, fc, lc);
690
691 if(!cc.IsNull()) {
692 //std::cout << "Pcurves exist" << std::endl;
693 return;
694 }
695
696 gp_Vec aN1, aN2;
697 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(fromFace),
698 TopoDS::Edge(aEdgeToUpdate), aN1);
699
700
701 TopOpeBRepBuild_Tools::GetNormalToFaceOnEdge(TopoDS::Face(toFace),
702 TopoDS::Edge(aEdgeToUpdate), aN2);
703
704 if(aN1*aN2 < 0)
705 DiffOriented = Standard_True;
706
707 Standard_Real tolE = BRep_Tool::Tolerance(newE);
708 Standard_Real f2 = 0., l2 = 0., tolpc = 0., tol = 0.;
709
710 //first PCurve
711 Handle(Geom2d_Curve) C2D = FC2D_CurveOnSurface(newE,
712 tFace, f2,
713 l2, tolpc, Standard_True);
714
715 tol = Max(tolpc, tolE);
716
717 BRepAdaptor_Surface aBAS(fFace);
718 gp_Vec2d aTrV;
719
720 Standard_Real ff = 0., lf = 0., fr = 0., lr = 0.;
721 gp_Pnt2d aUVf, aUVr;
722
723 Handle(Geom2d_Curve) oldC2DFor = BRep_Tool::CurveOnSurface(newE, //FC2D_CurveOnSurface(newE,
724 fFace, ff,
725 lf);//, tolpc, Standard_True);
726 newE.Reverse();
727 Handle(Geom2d_Curve) oldC2DRev = BRep_Tool::CurveOnSurface(newE, //FC2D_CurveOnSurface(newE,
728 fFace, fr,
729 lr);//, tolpc, Standard_True);
730
731 oldC2DFor -> D0(ff, aUVf);
732 oldC2DRev -> D0(fr, aUVr);
733
734 if(!DiffOriented)
735 aTrV = gp_Vec2d(aUVf, aUVr);
736 else
737 aTrV = gp_Vec2d(aUVr, aUVf);
738
739 gp_Vec2d aux(gp_Pnt2d(0., 0.), gp_Pnt2d(1., 1.));
740 Standard_Real scalar = aux*aTrV;
741 Standard_Boolean dir = (scalar >= 0.) ? Standard_True : Standard_False;
742
743 //compute right order of pcurves
744 gp_Vec2d aYVec(gp_Pnt2d(0., 0.), gp_Pnt2d(0., 1.));
745 gp_Pnt2d aUVfv, aUVlv;
746 C2D -> D0(f2, aUVfv);
747 C2D -> D0(l2, aUVlv);
748 gp_Vec2d C2DVec(aUVfv, aUVlv);
749
750 Standard_Boolean firstOrder = Standard_True;
751 scalar = aYVec*C2DVec;
752 if(fabs(scalar) <= 1e-10) {// compute along X axe
753 gp_Vec2d aXVec(gp_Pnt2d(0., 0.), gp_Pnt2d(1., 0.));
754 scalar = aXVec*C2DVec;
755 firstOrder = (scalar >= 0.) ? Standard_True : Standard_False;
756 }
757 else
758 firstOrder = (scalar > 0.) ? Standard_False : Standard_True;
759
760 Handle(Geom2d_Curve) aTrC = Handle(Geom2d_Curve)::DownCast(C2D->Copy());
761 aTrC -> Translate(aTrV);
762
763 if(dir) {
764 if(firstOrder)
765 BB.UpdateEdge(aEdgeToUpdate, C2D, aTrC, toFace, tol);
766 else
767 BB.UpdateEdge(aEdgeToUpdate, aTrC, C2D, toFace, tol);
768 }
769 else {
770 if(!firstOrder)
771 BB.UpdateEdge(aEdgeToUpdate, C2D, aTrC, toFace, tol);
772 else
773 BB.UpdateEdge(aEdgeToUpdate, aTrC, C2D, toFace, tol);
774 }
775 }
776
777 //=======================================================================
778 //function : TopOpeBRepBuild_Tools::IsDegEdgesTheSame
779 //purpose :
780 //=======================================================================
IsDegEdgesTheSame(const TopoDS_Shape & anE1,const TopoDS_Shape & anE2)781 Standard_Boolean TopOpeBRepBuild_Tools::IsDegEdgesTheSame (const TopoDS_Shape& anE1,
782 const TopoDS_Shape& anE2)
783 {
784 TopTools_IndexedMapOfShape aVMap1, aVMap2;
785 TopExp::MapShapes(anE1, TopAbs_VERTEX, aVMap1);
786 TopExp::MapShapes(anE2, TopAbs_VERTEX, aVMap2);
787
788 if (!aVMap1.Extent() || !aVMap2.Extent())
789 return Standard_False;
790
791 if (aVMap1(1).IsSame(aVMap2(1)))
792 return Standard_True;
793 else
794 return Standard_False;
795 }
796
797 //=======================================================================
798 //function : NormalizeFace
799 //purpose : remove all INTERNAL and EXTERNAL edges from the face
800 //=======================================================================
NormalizeFace(const TopoDS_Shape & oldFace,TopoDS_Shape & corrFace)801 void TopOpeBRepBuild_Tools::NormalizeFace(const TopoDS_Shape& oldFace,
802 TopoDS_Shape& corrFace)
803 {
804 Standard_Real tolF1;
805
806 TopLoc_Location Loc;
807 TopoDS_Face aF1 = TopoDS::Face(oldFace),
808 aNewFace;
809
810 aF1.Orientation(TopAbs_FORWARD);
811
812 Handle(Geom_Surface) Surf = BRep_Tool::Surface(aF1, Loc);
813 tolF1 = BRep_Tool::Tolerance(aF1);
814 BRep_Builder BB;
815 BB.MakeFace(aNewFace, Surf, Loc, tolF1);
816
817 TopExp_Explorer aFExp(aF1, TopAbs_WIRE);
818 for (; aFExp.More(); aFExp.Next()) {
819 Standard_Integer NbGoodEdges = 0;
820 TopoDS_Shape aWire=aFExp.Current();
821 aWire.Orientation(TopAbs_FORWARD);
822 TopoDS_Wire aNewWire;
823
824 BB.MakeWire(aNewWire);
825
826 TopExp_Explorer aWExp(aWire, TopAbs_EDGE);
827 for (; aWExp.More(); aWExp.Next()) {
828 TopoDS_Shape anEdge=aWExp.Current();
829
830 if (anEdge.Orientation()==TopAbs_EXTERNAL ||
831 anEdge.Orientation()==TopAbs_INTERNAL)
832 continue;
833
834 BB.Add (aNewWire, TopoDS::Edge(anEdge));
835 NbGoodEdges++;
836 }
837 //keep wire orientation
838 aNewWire.Orientation(aFExp.Current().Orientation());//aWire.Orientation());
839
840 if(NbGoodEdges) //we add new wire only if it contains at least one edge
841 BB.Add (aNewFace, aNewWire);
842 }
843 //keep face orientation
844 aNewFace.Orientation(oldFace.Orientation());
845
846 corrFace = aNewFace;
847 }
848
849
850 //=======================================================================
851 //function : CorrectFace2d
852 //purpose : adjust PCurves of periodical face in 2d
853 //=======================================================================
CorrectFace2d(const TopoDS_Shape & oldFace,TopoDS_Shape & corrFace,const TopTools_IndexedMapOfOrientedShape & aSourceShapes,TopTools_IndexedDataMapOfShapeShape & aMapOfCorrect2dEdges)854 void TopOpeBRepBuild_Tools::CorrectFace2d (const TopoDS_Shape& oldFace,
855 TopoDS_Shape& corrFace,
856 const TopTools_IndexedMapOfOrientedShape& aSourceShapes,
857 TopTools_IndexedDataMapOfShapeShape& aMapOfCorrect2dEdges)
858 {
859 TopOpeBRepBuild_CorrectFace2d aCorrectFace2d(TopoDS::Face(oldFace),
860 aSourceShapes,
861 aMapOfCorrect2dEdges);
862
863
864 aCorrectFace2d.Perform();
865 corrFace=oldFace;
866 }
867