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