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 |
77 | const 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 | //======================================================================= |
449 | void 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 | //======================================================================= |
511 | Standard_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 | //======================================================================= |
573 | Standard_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 | //======================================================================= |
597 | Standard_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 | //======================================================================= |
625 | void 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 | //======================================================================= |
641 | void 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 | //======================================================================= |
680 | void 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 | //======================================================================= |
783 | Standard_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 | //======================================================================= |
803 | void 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 | //======================================================================= |
856 | void 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 | } |