7fd59977 |
1 | // File: BRepFill.cxx |
2 | // Created: Thu Mar 3 11:18:14 1994 |
3 | // Author: Bruno DUMORTIER |
4 | // <dub@fuegox> |
5 | // Modified: Mon Jan 12 10:50:10 1998 |
6 | // Author: Joelle CHAUVET |
7 | // <jct@sgi64> |
8 | // gestion automatique de l'origine et de l'orientation |
9 | // avec la methode Organize |
10 | // Modified: Mon Feb 23 09:28:46 1998 |
11 | // Author: Joelle CHAUVET |
12 | // <jct@sgi64> |
13 | // methode Organize avec option de projection pour les wires fermes |
14 | // nouvelle methode SameNumber avec option de report des decoupes |
15 | // + utilitaires ComputeACR et InsertACR |
16 | // + traitement du cas derniere section ponctuelle |
17 | // Modified: Thu Apr 30 15:24:17 1998 |
18 | // Author: Joelle CHAUVET |
19 | // <jct@sgi64> |
20 | // separation sections fermees / sections ouvertes + debug |
21 | // Organize devient ComputeOrigin et SearchOrigin |
22 | // Modified: Tue Jul 21 16:48:35 1998 |
23 | // Author: Joelle CHAUVET |
24 | // <jct@sgi64> |
25 | // cas limite pour Pnext d'ou vrillage (BUC60281) |
26 | // Modified: Thu Jul 23 11:38:36 1998 |
27 | // Author: Joelle CHAUVET |
28 | // <jct@sgi64> |
29 | // calcul de l'angle de la rotation dans SearchOrigin |
30 | // Modified: Fri Jul 31 15:14:19 1998 |
31 | // Author: Joelle CHAUVET |
32 | // <jct@sgi64> |
33 | // IntersectOnWire + MapVLV |
34 | // Modified: Mon Oct 12 09:42:33 1998 |
35 | // Author: Joelle CHAUVET |
36 | // <jct@sgi64> |
37 | // numero des aretes dans EdgesFromVertex (CTS21570) |
38 | |
39 | #include <BRepFill.ixx> |
40 | |
41 | #include <BRepLib.hxx> |
42 | #include <BRepLib_FindSurface.hxx> |
43 | #include <BRepLib_MakeFace.hxx> |
44 | #include <BRepLib_MakeEdge.hxx> |
45 | #include <BRepLib_MakeVertex.hxx> |
46 | #include <BRepLib_MakeWire.hxx> |
47 | #include <BRepExtrema_ExtPC.hxx> |
48 | #include <BRepExtrema_DistShapeShape.hxx> |
49 | #include <BRep_Tool.hxx> |
50 | #include <BRepTools_WireExplorer.hxx> |
51 | |
52 | #include <TopoDS_Face.hxx> |
53 | #include <TopoDS_Wire.hxx> |
54 | #include <TopoDS_Vertex.hxx> |
55 | #include <BRep_Builder.hxx> |
56 | #include <TopLoc_Location.hxx> |
57 | #include <TopExp_Explorer.hxx> |
58 | #include <gp_Vec.hxx> |
59 | #include <gp_Lin.hxx> |
60 | #include <gp_Pln.hxx> |
61 | #include <gp_Pnt2d.hxx> |
62 | #include <gp_Dir.hxx> |
63 | #include <gp_Dir2d.hxx> |
64 | #include <gp_Circ.hxx> |
65 | #include <gp_Elips.hxx> |
66 | #include <Geom_Curve.hxx> |
67 | #include <Geom_TrimmedCurve.hxx> |
68 | #include <Geom_Surface.hxx> |
69 | #include <Geom_Plane.hxx> |
70 | #include <Geom2d_Line.hxx> |
71 | #include <GeomFill_Generator.hxx> |
72 | #include <GeomAdaptor_Curve.hxx> |
73 | #include <BRepLProp.hxx> |
74 | #include <BRepGProp.hxx> |
75 | #include <GProp_GProps.hxx> |
76 | #include <GProp_PrincipalProps.hxx> |
77 | #include <GCPnts_AbscissaPoint.hxx> |
78 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> |
79 | #include <TopTools_DataMapOfShapeListOfShape.hxx> |
80 | #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx> |
81 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
82 | #include <TopTools_ListOfShape.hxx> |
83 | #include <TopTools_Array1OfShape.hxx> |
84 | #include <TopTools_SequenceOfShape.hxx> |
85 | #include <TopTools_HSequenceOfShape.hxx> |
86 | #include <BRepAdaptor_Curve.hxx> |
87 | #include <TopTools_IndexedMapOfShape.hxx> |
88 | |
89 | #include <BRep_Tool.hxx> |
90 | #include <TopoDS.hxx> |
91 | #include <TopExp.hxx> |
92 | #include <Precision.hxx> |
93 | |
94 | #include <TColStd_Array1OfInteger.hxx> |
95 | #include <Standard_NoSuchObject.hxx> |
96 | |
97 | |
98 | static void MakeWire(const TopTools_Array1OfShape& Edges, |
99 | const Standard_Integer rangdeb, |
100 | const Standard_Boolean forward, |
101 | TopoDS_Wire& newwire) |
102 | { |
103 | BRep_Builder BW; |
104 | Standard_Integer rang, nbEdges = Edges.Length(); |
105 | BW.MakeWire(newwire); |
106 | if (forward) { |
107 | for (rang=rangdeb;rang<=nbEdges;rang++) { |
108 | BW.Add(newwire,TopoDS::Edge(Edges(rang))); |
109 | } |
110 | for (rang=1;rang<rangdeb;rang++) { |
111 | BW.Add(newwire,TopoDS::Edge(Edges(rang))); |
112 | } |
113 | } |
114 | |
115 | else { |
116 | TopoDS_Edge E; |
117 | for (rang=rangdeb;rang>=1;rang--) { |
118 | E = TopoDS::Edge(Edges(rang)); |
119 | BW.Add(newwire,E.Reversed()); |
120 | } |
121 | for (rang=nbEdges;rang>rangdeb;rang--) { |
122 | E = TopoDS::Edge(Edges(rang)); |
123 | BW.Add(newwire, E.Reversed()); |
124 | } |
125 | } |
126 | newwire.Orientation(TopAbs_FORWARD); |
127 | } |
128 | |
129 | static void CutEdge(const TopoDS_Edge& CurrentEdge, |
130 | const Standard_Real& Param, |
131 | TopoDS_Edge& E1, |
132 | TopoDS_Edge& E2, |
133 | const TopoDS_Vertex& VRef) |
134 | { |
135 | BRep_Builder B; |
136 | Standard_Real first,last; |
137 | Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last); |
138 | TopoDS_Vertex Vf, Vl, Vi; |
139 | B.MakeVertex(Vi, C->Value(Param), Precision::Confusion()); |
140 | TopExp::Vertices(CurrentEdge, Vf, Vl); |
141 | if (VRef.IsSame(Vf)) { |
142 | E1 = BRepLib_MakeEdge(C,Vf,Vi, first,Param); |
143 | E2 = BRepLib_MakeEdge(C,Vi,Vl, Param,last); |
144 | } |
145 | else { |
146 | E2 = BRepLib_MakeEdge(C,Vf,Vi, first,Param); |
147 | E1 = BRepLib_MakeEdge(C,Vi,Vl, Param,last); |
148 | } |
149 | } |
150 | |
151 | |
152 | static void TrimEdge (const TopoDS_Edge& CurrentEdge, |
153 | const TColStd_SequenceOfReal& CutValues, |
154 | const Standard_Real t0, const Standard_Real t1, |
155 | const Standard_Boolean SeqOrder, |
156 | TopTools_SequenceOfShape& S) |
157 | |
158 | { |
159 | S.Clear(); |
160 | Standard_Integer j, ndec=CutValues.Length(); |
161 | Standard_Real first,last,m0,m1; |
162 | Handle(Geom_Curve) C = BRep_Tool::Curve(CurrentEdge,first,last); |
163 | |
164 | TopoDS_Vertex Vf,Vl,Vbid,V0,V1; |
165 | TopAbs_Orientation CurrentOrient = CurrentEdge.Orientation(); |
166 | TopExp::Vertices(CurrentEdge,Vf,Vl); |
167 | Vbid.Nullify(); |
168 | |
169 | if (SeqOrder) { |
170 | // de first vers last |
171 | m0 = first; |
172 | V0 = Vf; |
173 | for (j=1; j<=ndec; j++) { |
174 | // morceau d'edge |
175 | m1 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first; |
176 | TopoDS_Edge CutE = BRepLib_MakeEdge(C,V0,Vbid,m0,m1); |
177 | CutE.Orientation(CurrentOrient); |
178 | S.Append(CutE); |
179 | m0 = m1; |
180 | V0 = TopExp::LastVertex(CutE); |
181 | if (j==ndec) { |
182 | // dernier morceau |
183 | TopoDS_Edge LastE = BRepLib_MakeEdge(C,V0,Vl,m0,last); |
184 | LastE.Orientation(CurrentOrient); |
185 | S.Append(LastE); |
186 | } |
187 | } |
188 | } |
189 | else { |
190 | // de last vers first |
191 | m1 = last; |
192 | V1 = Vl; |
193 | for (j=ndec; j>=1; j--) { |
194 | // morceau d'edge |
195 | m0 = (CutValues.Value(j)-t0)*(last-first)/(t1-t0)+first; |
196 | TopoDS_Edge CutE = BRepLib_MakeEdge(C,Vbid,V1,m0,m1); |
197 | CutE.Orientation(CurrentOrient); |
198 | S.Append(CutE); |
199 | m1 = m0; |
200 | V1 = TopExp::FirstVertex(CutE); |
201 | if (j==1) { |
202 | // dernier morceau |
203 | TopoDS_Edge LastE = BRepLib_MakeEdge(C,Vf,V1,first,m1); |
204 | LastE.Orientation(CurrentOrient); |
205 | S.Append(LastE); |
206 | } |
207 | } |
208 | } |
209 | } |
210 | |
211 | |
212 | //======================================================================= |
213 | //function : Face |
214 | //purpose : |
215 | //======================================================================= |
216 | |
217 | TopoDS_Face BRepFill::Face(const TopoDS_Edge& Edge1, |
218 | const TopoDS_Edge& Edge2 ) |
219 | { |
220 | TopoDS_Face Face; |
221 | |
222 | BRep_Builder B; |
223 | // Class BRep_Tool without fields and without Constructor : |
224 | // BRep_Tool BT; |
225 | |
226 | TopLoc_Location L,L1,L2; |
227 | Standard_Real f1,f2,l1,l2, Tol; |
228 | |
229 | // Handle(Geom_Curve) C1 = BT.Curve(Edge1,L1,f1,l1); |
230 | Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1); |
231 | // Handle(Geom_Curve) C2 = BT.Curve(Edge2,L2,f2,l2); |
232 | Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2); |
233 | |
234 | // compute the location |
235 | Standard_Boolean SameLoc = Standard_False; |
236 | if (L1 == L2) { |
237 | L = L1; |
238 | L1 = L2 = TopLoc_Location(); |
239 | SameLoc = Standard_True; |
240 | } |
241 | |
242 | // transform and trim the curves |
243 | |
244 | TopoDS_Vertex V1f,V1l,V2f,V2l; |
245 | |
246 | // on cree un new Handle |
247 | if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() || |
248 | Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) { |
249 | C1 = new Geom_TrimmedCurve(C1,f1,l1); |
250 | } |
251 | else { |
252 | C1 = Handle(Geom_Curve)::DownCast(C1->Copy()); |
253 | } |
254 | // eventuellement on bouge la courbe |
255 | if ( !SameLoc) { |
256 | C1->Transform(L1.Transformation()); |
257 | } |
258 | // on la met dans le bon sens et on prend ses vertex |
259 | if (Edge1.Orientation() == TopAbs_REVERSED) { |
260 | TopExp::Vertices(Edge1,V1l,V1f); |
261 | C1->Reverse(); |
262 | } |
263 | else { |
264 | TopExp::Vertices(Edge1,V1f,V1l); |
265 | } |
266 | |
267 | // on cree un new Handle |
268 | if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() || |
269 | Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) { |
270 | C2 = new Geom_TrimmedCurve(C2,f2,l2); |
271 | } |
272 | else { |
273 | C2 = Handle(Geom_Curve)::DownCast(C2->Copy()); |
274 | } |
275 | // eventuellement on bouge la courbe |
276 | if ( !SameLoc) { |
277 | C2->Transform(L2.Transformation()); |
278 | } |
279 | // on la met dans le bon sens et on prend ses vertex |
280 | if (Edge2.Orientation() == TopAbs_REVERSED) { |
281 | TopExp::Vertices(Edge2,V2l,V2f); |
282 | C2->Reverse(); |
283 | } |
284 | else { |
285 | TopExp::Vertices(Edge2,V2f,V2l); |
286 | } |
287 | |
288 | // Sont-ce des edges fermes |
289 | Standard_Boolean Closed = V1f.IsSame(V1l) && V2f.IsSame(V2l); |
290 | |
291 | |
292 | GeomFill_Generator Generator; |
293 | Generator.AddCurve( C1); |
294 | Generator.AddCurve( C2); |
295 | Generator.Perform( Precision::PConfusion()); |
296 | |
297 | Handle(Geom_Surface) Surf = Generator.Surface(); |
298 | Handle(Geom_Curve) Iso; |
299 | |
300 | B.MakeFace(Face,Surf,Precision::Confusion()); |
301 | |
302 | // make the missing edges |
303 | Surf->Bounds(f1,l1,f2,l2); |
304 | |
305 | TopoDS_Edge Edge3, Edge4; |
306 | |
307 | Iso = Surf->UIso(f1); |
308 | // Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f)); |
309 | Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f)); |
310 | if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) { |
311 | B.MakeEdge(Edge3,Iso,Precision::Confusion()); |
312 | } |
313 | else { |
314 | B.MakeEdge(Edge3); |
315 | B.Degenerated(Edge3, Standard_True); |
316 | } |
317 | V1f.Orientation(TopAbs_FORWARD); |
318 | B.Add(Edge3,V1f); |
319 | V2f.Orientation(TopAbs_REVERSED); |
320 | B.Add(Edge3,V2f); |
321 | B.Range(Edge3,f2,l2); |
322 | |
323 | if (Closed) { |
324 | Edge4 = Edge3; |
325 | } |
326 | else { |
327 | Iso = Surf->UIso(l1); |
328 | // Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l)); |
329 | Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l)); |
330 | if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) { |
331 | B.MakeEdge(Edge4,Iso,Precision::Confusion()); |
332 | } |
333 | else { |
334 | B.MakeEdge(Edge4); |
335 | B.Degenerated(Edge4, Standard_True); |
336 | } |
337 | V1l.Orientation(TopAbs_FORWARD); |
338 | B.Add(Edge4,V1l); |
339 | V2l.Orientation(TopAbs_REVERSED); |
340 | B.Add(Edge4,V2l); |
341 | B.Range(Edge4,f2,l2); |
342 | } |
343 | |
344 | // make the wire |
345 | |
346 | TopoDS_Wire W; |
347 | B.MakeWire(W); |
348 | |
349 | Edge3.Reverse(); |
350 | B.Add(W,Edge1); |
351 | B.Add(W,Edge4); |
352 | B.Add(W,Edge2.Reversed()); |
353 | B.Add(W,Edge3); |
354 | |
355 | B.Add(Face,W); |
356 | |
357 | // set the pcurves |
358 | |
359 | Standard_Real T = Precision::Confusion(); |
360 | |
361 | if ( Edge1.Orientation() == TopAbs_REVERSED ) { |
362 | B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)),Face,T); |
363 | B.Range(Edge1,Face,-l1,-f1); |
364 | } |
365 | else { |
366 | B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)),Face,T); |
367 | B.Range(Edge1,Face,f1,l1); |
368 | } |
369 | |
370 | if ( Edge2.Orientation() == TopAbs_REVERSED ) { |
371 | B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)),Face,T); |
372 | B.Range(Edge2,Face,-l1,-f1); |
373 | } |
374 | else { |
375 | B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)),Face,T); |
376 | B.Range(Edge2,Face,f1,l1); |
377 | } |
378 | |
379 | if ( Closed) { |
380 | B.UpdateEdge(Edge3, |
381 | new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)), |
382 | new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T); |
383 | } |
384 | else { |
385 | B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T); |
386 | B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T); |
387 | } |
388 | |
389 | // Set the non parameter flag; |
390 | B.SameParameter(Edge1,Standard_False); |
391 | B.SameParameter(Edge2,Standard_False); |
392 | B.SameParameter(Edge3,Standard_False); |
393 | B.SameParameter(Edge4,Standard_False); |
394 | B.SameRange(Edge1,Standard_False); |
395 | B.SameRange(Edge2,Standard_False); |
396 | B.SameRange(Edge3,Standard_False); |
397 | B.SameRange(Edge4,Standard_False); |
398 | |
399 | BRepLib::SameParameter(Face); |
400 | |
401 | if ( SameLoc) Face.Move(L); |
402 | return Face; |
403 | } |
404 | |
405 | |
406 | //======================================================================= |
407 | //function : Shell |
408 | //purpose : |
409 | //======================================================================= |
410 | |
411 | TopoDS_Shell BRepFill::Shell(const TopoDS_Wire& Wire1, |
412 | const TopoDS_Wire& Wire2 ) |
413 | { |
414 | TopoDS_Shell Shell; |
415 | TopoDS_Face Face; |
416 | TopoDS_Shape S1, S2; |
417 | TopoDS_Edge Edge1, Edge2, Edge3, Edge4, Couture; |
418 | |
419 | BRep_Builder B; |
420 | // Class BRep_Tool without fields and without Constructor : |
421 | // BRep_Tool BT; |
422 | B.MakeShell(Shell); |
423 | |
424 | TopExp_Explorer ex1; |
425 | TopExp_Explorer ex2; |
426 | |
427 | Standard_Boolean Closed = Wire1.Closed() && Wire2.Closed(); |
428 | |
429 | Standard_Boolean thefirst = Standard_True; |
430 | |
431 | ex1.Init(Wire1,TopAbs_EDGE); |
432 | ex2.Init(Wire2,TopAbs_EDGE); |
433 | |
434 | while ( ex1.More() && ex2.More() ) { |
435 | |
436 | Edge1 = TopoDS::Edge(ex1.Current()); |
437 | Edge2 = TopoDS::Edge(ex2.Current()); |
438 | |
439 | Standard_Boolean Periodic = Edge1.Closed() && Edge2.Closed(); |
440 | |
441 | ex1.Next(); |
442 | ex2.Next(); |
443 | |
444 | TopLoc_Location L,L1,L2; |
445 | Standard_Real f1,l1,f2,l2,Tol; |
446 | |
447 | Handle(Geom_Curve) C1 = BRep_Tool::Curve(Edge1,L1,f1,l1); |
448 | Handle(Geom_Curve) C2 = BRep_Tool::Curve(Edge2,L2,f2,l2); |
449 | |
450 | // compute the location |
451 | Standard_Boolean SameLoc = Standard_False; |
452 | if (L1 == L2) { |
453 | L = L1; |
454 | L1 = L2 = TopLoc_Location(); |
455 | SameLoc = Standard_True; |
456 | } |
457 | |
458 | // transform and trim the curves |
459 | |
460 | TopoDS_Vertex V1f,V1l,V2f,V2l; |
461 | |
462 | |
463 | if (Abs(f1 - C1->FirstParameter()) > Precision::PConfusion() || |
464 | Abs(l1 - C1->LastParameter()) > Precision::PConfusion() ) { |
465 | C1 = new Geom_TrimmedCurve(C1,f1,l1); |
466 | } |
467 | else { |
468 | C1 = Handle(Geom_Curve)::DownCast(C1->Copy()); |
469 | } |
470 | if ( !SameLoc) { |
471 | C1->Transform(L1.Transformation()); |
472 | } |
473 | if (Edge1.Orientation() == TopAbs_REVERSED) { |
474 | TopExp::Vertices(Edge1,V1l,V1f); |
475 | C1->Reverse(); |
476 | } |
477 | else |
478 | TopExp::Vertices(Edge1,V1f,V1l); |
479 | |
480 | if (Abs(f2 - C2->FirstParameter()) > Precision::PConfusion() || |
481 | Abs(l2 - C2->LastParameter()) > Precision::PConfusion() ) { |
482 | C2 = new Geom_TrimmedCurve(C2,f2,l2); |
483 | } |
484 | else { |
485 | C2 = Handle(Geom_Curve)::DownCast(C2->Copy()); |
486 | } |
487 | if ( !SameLoc) { |
488 | C2->Transform(L2.Transformation()); |
489 | } |
490 | if (Edge2.Orientation() == TopAbs_REVERSED) { |
491 | TopExp::Vertices(Edge2,V2l,V2f); |
492 | C2->Reverse(); |
493 | } |
494 | else |
495 | TopExp::Vertices(Edge2,V2f,V2l); |
496 | |
497 | GeomFill_Generator Generator; |
498 | Generator.AddCurve( C1); |
499 | Generator.AddCurve( C2); |
500 | Generator.Perform( Precision::PConfusion()); |
501 | |
502 | Handle(Geom_Surface) Surf = Generator.Surface(); |
503 | Handle(Geom_Curve) Iso; |
504 | |
505 | B.MakeFace(Face,Surf,Precision::Confusion()); |
506 | |
507 | // make the missing edges |
508 | Surf->Bounds(f1,l1,f2,l2); |
509 | |
510 | if ( thefirst) { |
511 | Iso = Surf->UIso(f1); |
512 | // Tol = Max(BT.Tolerance(V1f), BT.Tolerance(V2f)); |
513 | Tol = Max(BRep_Tool::Tolerance(V1f), BRep_Tool::Tolerance(V2f)); |
514 | if (Iso->Value(f2).Distance(Iso->Value(l2)) > Tol) { |
515 | B.MakeEdge(Edge3,Iso,Precision::Confusion()); |
516 | } |
517 | else { |
518 | B.MakeEdge(Edge3); |
519 | B.Degenerated(Edge3, Standard_True); |
520 | } |
521 | V1f.Orientation(TopAbs_FORWARD); |
522 | B.Add(Edge3,V1f); |
523 | V2f.Orientation(TopAbs_REVERSED); |
524 | B.Add(Edge3,V2f); |
525 | B.Range(Edge3,f2,l2); |
526 | if ( Closed) { |
527 | Couture = Edge3; |
528 | } |
529 | Edge3.Reverse(); |
530 | thefirst = Standard_False; |
531 | } |
532 | else { |
533 | Edge3 = Edge4; |
534 | Edge3.Reverse(); |
535 | } |
536 | |
537 | if ( Closed && !ex1.More() && !ex2.More() ) { |
538 | Edge4 = Couture; |
539 | } |
540 | else { |
541 | Iso = Surf->UIso(l1); |
542 | // Tol = Max(BT.Tolerance(V1l), BT.Tolerance(V2l)); |
543 | Tol = Max(BRep_Tool::Tolerance(V1l), BRep_Tool::Tolerance(V2l)); |
544 | if (Iso->Value(l2).Distance(Iso->Value(f2)) > Tol) { |
545 | B.MakeEdge(Edge4,Iso,Precision::Confusion()); |
546 | } |
547 | else { |
548 | B.MakeEdge(Edge4); |
549 | B.Degenerated(Edge4, Standard_True); |
550 | } |
551 | V1l.Orientation(TopAbs_FORWARD); |
552 | B.Add(Edge4,V1l); |
553 | V2l.Orientation(TopAbs_REVERSED); |
554 | B.Add(Edge4,V2l); |
555 | B.Range(Edge4,f2,l2); |
556 | } |
557 | |
558 | // make the wire |
559 | |
560 | TopoDS_Wire W; |
561 | B.MakeWire(W); |
562 | |
563 | B.Add(W,Edge1); |
564 | B.Add(W,Edge4); |
565 | B.Add(W,Edge2.Reversed()); |
566 | B.Add(W,Edge3); |
567 | |
568 | B.Add(Face,W); |
569 | |
570 | if ( SameLoc) Face.Move( L); |
571 | |
572 | B.Add(Shell,Face); |
573 | |
574 | // set the pcurves |
575 | |
576 | Standard_Real T = Precision::Confusion(); |
577 | |
578 | if ( Edge1.Orientation() == TopAbs_REVERSED ) { |
579 | B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(-1,0)), |
580 | Face,T); |
581 | B.Range(Edge1,Face,-l1,-f1); |
582 | } |
583 | else { |
584 | B.UpdateEdge(Edge1,new Geom2d_Line(gp_Pnt2d(0,f2),gp_Dir2d(1,0)), |
585 | Face,T); |
586 | B.Range(Edge1,Face,f1,l1); |
587 | } |
588 | |
589 | if ( Edge2.Orientation() == TopAbs_REVERSED ) { |
590 | B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(-1,0)), |
591 | Face,T); |
592 | B.Range(Edge2,Face,-l1,-f1); |
593 | } |
594 | else { |
595 | B.UpdateEdge(Edge2,new Geom2d_Line(gp_Pnt2d(0,l2),gp_Dir2d(1,0)), |
596 | Face,T); |
597 | B.Range(Edge2,Face,f1,l1); |
598 | } |
599 | |
600 | if ( Periodic) { |
601 | B.UpdateEdge(Edge3, |
602 | new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)), |
603 | new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)), |
604 | Face,T); |
605 | } |
606 | else { |
607 | B.UpdateEdge(Edge3,new Geom2d_Line(gp_Pnt2d(f1,0),gp_Dir2d(0,1)),Face,T); |
608 | B.UpdateEdge(Edge4,new Geom2d_Line(gp_Pnt2d(l1,0),gp_Dir2d(0,1)),Face,T); |
609 | } |
610 | |
611 | // Set the non parameter flag; |
612 | B.SameParameter(Edge1,Standard_False); |
613 | B.SameParameter(Edge2,Standard_False); |
614 | B.SameParameter(Edge3,Standard_False); |
615 | B.SameParameter(Edge4,Standard_False); |
616 | B.SameRange(Edge1,Standard_False); |
617 | B.SameRange(Edge2,Standard_False); |
618 | B.SameRange(Edge3,Standard_False); |
619 | B.SameRange(Edge4,Standard_False); |
620 | } |
621 | |
622 | BRepLib::SameParameter(Shell); |
623 | return Shell; |
624 | } |
625 | |
626 | //======================================================================= |
627 | //function : Axe |
628 | //purpose : |
629 | //======================================================================= |
630 | |
631 | void BRepFill::Axe (const TopoDS_Shape& Spine, |
632 | const TopoDS_Wire& Profile, |
633 | gp_Ax3& AxeProf, |
634 | Standard_Boolean& ProfOnSpine, |
635 | const Standard_Real Tol) |
636 | { |
637 | gp_Pnt Loc,Loc1,Loc2; |
638 | gp_Vec Tang,Tang1,Tang2,Normal; |
639 | |
640 | Handle(Geom_Surface) S; |
641 | TopLoc_Location L; |
642 | |
643 | TopoDS_Face aFace; |
644 | |
645 | // normale au Spine. |
646 | if (Spine.ShapeType() == TopAbs_FACE) { |
647 | aFace = TopoDS::Face(Spine); |
648 | S = BRep_Tool::Surface(TopoDS::Face(Spine), L); |
649 | if ( !S->IsKind(STANDARD_TYPE(Geom_Plane))) { |
650 | BRepLib_FindSurface FS(TopoDS::Face(Spine), -1, Standard_True); |
651 | if ( FS.Found()) { |
652 | S = FS.Surface(); |
653 | L = FS.Location(); |
654 | } |
655 | else { |
656 | Standard_NoSuchObject::Raise |
657 | ("BRepFill_Evolved : The Face is not planar"); |
658 | } |
659 | } |
660 | } |
661 | else if (Spine.ShapeType() == TopAbs_WIRE) { |
662 | aFace = BRepLib_MakeFace(TopoDS::Wire(Spine),Standard_True); |
663 | S = BRep_Tool::Surface(aFace, L); |
664 | } |
665 | |
666 | if (S.IsNull()) Standard_DomainError::Raise("BRepFill_Evolved::Axe"); |
667 | |
668 | if (!L.IsIdentity()) |
669 | S = Handle(Geom_Surface)::DownCast(S->Transformed(L.Transformation())); |
670 | |
671 | Normal = Handle(Geom_Plane)::DownCast(S)->Pln().Axis().Direction(); |
672 | |
673 | // Recherche du vertex du profil le plus proche du spine. |
674 | Standard_Real DistMin = Precision::Infinite(); |
675 | Standard_Real Dist; |
676 | // Standard_Real Tol2 = Tol*Tol; |
677 | Standard_Real Tol2 = 1.e-10; |
678 | TopExp_Explorer PE, SE; |
679 | BRepExtrema_ExtPC BE; |
680 | Standard_Real Par =0.,f,l; |
681 | // Standard_Real D1,D2; |
682 | gp_Pnt P1,P2; |
683 | |
684 | // On cherche d'abord si il y a contact Vertex Vertex. |
685 | Standard_Boolean IsOnVertex = Standard_False; |
686 | SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_VERTEX); |
687 | // modified by NIZHNY-EAP Wed Feb 23 12:31:52 2000 ___BEGIN___ |
688 | // for (;SE.More() && !IsOnVertex ; SE.Next()) { |
689 | for (;SE.More(); SE.Next()) { |
690 | P1 = BRep_Tool::Pnt(TopoDS::Vertex(SE.Current())); |
691 | |
692 | PE.Init(Profile,TopAbs_VERTEX); |
693 | for ( ; PE.More(); PE.Next()) { |
694 | P2 = BRep_Tool::Pnt(TopoDS::Vertex(PE.Current())); |
695 | Standard_Real DistP1P2 = P1.SquareDistance(P2); |
696 | IsOnVertex = (DistP1P2 <= Tol2); |
697 | if (IsOnVertex) break; |
698 | } |
699 | // otherwise SE.Next() is done and VonF is wrong |
700 | if (IsOnVertex) break; |
701 | // modified by NIZHNY-EAP Wed Jan 26 09:08:36 2000 ___END___ |
702 | } |
703 | |
704 | if (IsOnVertex) { |
705 | // try to find on which edge which shared this vertex, |
706 | // the profile must be considered. |
707 | // E1, E2 : those two edges. |
708 | TopTools_IndexedDataMapOfShapeListOfShape Map; |
709 | TopExp::MapShapesAndAncestors(aFace.Oriented(TopAbs_FORWARD), |
710 | TopAbs_VERTEX, |
711 | TopAbs_EDGE, |
712 | Map); |
713 | |
714 | const TopoDS_Vertex& VonF = TopoDS::Vertex(SE.Current()); |
715 | const TopTools_ListOfShape& List = Map.FindFromKey(VonF); |
716 | const TopoDS_Edge& E1 = TopoDS::Edge(List.First()); |
717 | const TopoDS_Edge& E2 = TopoDS::Edge(List. Last()); |
718 | |
719 | Handle(Geom_Curve) CE1 = BRep_Tool::Curve(E1,L,f,l); |
720 | Standard_Real Par1 = BRep_Tool::Parameter(VonF,E1,aFace); |
721 | CE1->D1(Par1,Loc1,Tang1); |
722 | if (!L.IsIdentity()) { |
723 | Tang1.Transform(L.Transformation()); |
724 | Loc1.Transform(L.Transformation()); |
725 | } |
726 | if (E1.Orientation() == TopAbs_REVERSED) Tang1.Reverse(); |
727 | |
728 | Handle(Geom_Curve) CE2 = BRep_Tool::Curve(E2,L,f,l); |
729 | Standard_Real Par2 = BRep_Tool::Parameter(VonF,E2,aFace); |
730 | CE2->D1(Par2,Loc2,Tang2); |
731 | if (!L.IsIdentity()) { |
732 | Tang2.Transform(L.Transformation()); |
733 | Loc2.Transform(L.Transformation()); |
734 | } |
735 | if (E2.Orientation() == TopAbs_REVERSED) Tang2.Reverse(); |
736 | |
737 | // modified by NIZHNY-EAP Wed Feb 2 15:38:41 2000 ___BEGIN___ |
738 | Tang1.Normalize(); |
739 | Tang2.Normalize(); |
740 | Standard_Real sca1=0., sca2=0.; |
741 | TopoDS_Vertex V1, V2; |
742 | TopoDS_Edge E; |
743 | for (PE.Init(Profile,TopAbs_EDGE); PE.More(); PE.Next()) { |
744 | E = TopoDS::Edge(PE.Current()); |
745 | TopExp::Vertices(E, V1, V2); |
746 | P1 = BRep_Tool::Pnt(V1); |
747 | P2 = BRep_Tool::Pnt(V2); |
748 | gp_Vec vec(P1,P2); |
749 | sca1 += Abs(Tang1.Dot(vec)); |
750 | sca2 += Abs(Tang2.Dot(vec)); |
751 | } |
752 | // modified by NIZHNY-EAP Wed Feb 2 15:38:44 2000 ___END___ |
753 | |
754 | if ( Abs(sca1) < Abs(sca2)) { |
755 | Loc = Loc1; |
756 | Tang = Tang1; |
757 | } |
758 | else { |
759 | Loc = Loc2; |
760 | Tang = Tang2; |
761 | } |
762 | DistMin = 0.; |
763 | } |
764 | else { |
765 | SE.Init(aFace.Oriented(TopAbs_FORWARD),TopAbs_EDGE); |
766 | for ( ; SE.More(); SE.Next()) { |
767 | const TopoDS_Edge& E = TopoDS::Edge(SE.Current()); |
768 | BE.Initialize(E); |
769 | for (PE.Init(Profile,TopAbs_VERTEX) ; PE.More(); PE.Next()) { |
770 | Dist = Precision::Infinite(); |
771 | const TopoDS_Vertex& V = TopoDS::Vertex(PE.Current()); |
772 | BE.Perform(V); |
773 | if (BE.IsDone()) { |
774 | // extrema. |
775 | for (Standard_Integer i = 1; i <= BE.NbExt(); i++) { |
776 | if (BE.IsMin(i)) { |
777 | Dist = sqrt (BE.SquareDistance(i)); |
778 | Par = BE.Parameter(i); |
779 | break; |
780 | } |
781 | } |
782 | } |
783 | // sauvegarde minimum. |
784 | if (Dist < DistMin) { |
785 | DistMin = Dist; |
786 | BRepAdaptor_Curve BAC(E); |
787 | BAC.D1 (Par,Loc,Tang); |
788 | if (E.Orientation() == TopAbs_REVERSED) Tang.Reverse(); |
789 | } |
790 | } |
791 | } |
792 | } |
793 | |
794 | ProfOnSpine = (DistMin < Tol); |
795 | //Construction AxeProf; |
796 | gp_Ax3 A3 (Loc,Normal,Tang); |
797 | AxeProf = A3; |
798 | |
799 | } |
800 | |
801 | //======================================================================= |
802 | //function : SearchOrigin |
803 | //purpose : Decoupe et oriente un wire ferme. |
804 | //======================================================================= |
805 | |
806 | void BRepFill::SearchOrigin(TopoDS_Wire & W, |
807 | const gp_Pnt& P, |
808 | const gp_Vec& Dir, |
809 | const Standard_Real Tol) |
810 | { |
811 | if (!W.Closed()) |
812 | Standard_NoSuchObject:: |
813 | Raise("BRepFill::SearchOrigin : the wire must be closed"); |
814 | |
815 | |
816 | Standard_Boolean NewVertex = Standard_False; |
817 | Standard_Real theparam = 1.e101, angle; |
818 | TopoDS_Vertex V ; |
819 | TopoDS_Edge E, Eref, E1 , E2; |
820 | BRep_Builder B; |
821 | // Class BRep_Tool without fields and without Constructor : |
822 | // BRep_Tool BT; |
823 | |
824 | W.Orientation(TopAbs_FORWARD); //pour ne pas composer les orientations |
825 | |
826 | // Calcul la distance |
827 | B.MakeVertex(V, P, Tol); |
828 | BRepExtrema_DistShapeShape DSS(V, W); |
829 | if (DSS.IsDone()) { |
830 | Standard_Integer isol = 1; |
831 | Standard_Real dss = P.Distance(DSS.PointOnShape2(isol)); |
832 | for (Standard_Integer iss=2; iss<=DSS.NbSolution(); iss++) |
833 | if (dss > P.Distance(DSS.PointOnShape2(iss))) { |
834 | dss = P.Distance(DSS.PointOnShape2(iss)); |
835 | isol = iss; |
836 | } |
837 | TopoDS_Shape supp = DSS.SupportOnShape2(isol); |
838 | if (DSS.SupportTypeShape2(isol)==BRepExtrema_IsVertex) { |
839 | V = TopoDS::Vertex(supp); |
840 | } |
841 | else { |
842 | TopoDS_Vertex Vf, Vl; |
843 | Standard_Real d, dist; |
844 | E = TopoDS::Edge(supp); |
845 | TopExp::Vertices(E, Vf, Vl); |
846 | // dist = P.Distance(BT.Pnt(Vf)); |
847 | dist = P.Distance(BRep_Tool::Pnt(Vf)); |
848 | if (dist < Tol) { |
849 | V = Vl; |
850 | } |
851 | // d = P.Distance(BT.Pnt(Vl)); |
852 | d = P.Distance(BRep_Tool::Pnt(Vl)); |
853 | if ((d<Tol) && (d<dist)) { |
854 | V = Vf; |
855 | dist = d; |
856 | } |
857 | NewVertex = (dist > Tol); |
858 | if (NewVertex) { |
859 | DSS.ParOnEdgeS2(isol, theparam); |
860 | } |
861 | } |
862 | } |
863 | #if DEB |
864 | else { |
865 | cout << "BRepFill::SearchOrigine : Echec Distance" << endl; |
866 | } |
867 | #endif |
868 | |
869 | Standard_Integer ii, rangdeb=0, NbEdges=0; |
870 | Standard_Boolean forward; |
871 | BRepTools_WireExplorer exp; |
872 | |
873 | // Calcul le nombre d'edges |
874 | for(exp.Init(W); exp.More(); exp.Next()) NbEdges++; |
875 | if (NewVertex) { |
876 | NbEdges++; |
877 | Eref = E; |
878 | } |
879 | |
880 | // Construit la Table et calcul rangdeb |
881 | TopTools_Array1OfShape Edges(1, NbEdges); |
882 | for(exp.Init(W), ii=1; exp.More(); exp.Next(), ii++) { |
883 | E = exp.Current(); |
884 | if (NewVertex && E.IsSame(Eref)) { |
885 | TopoDS_Edge E1, E2; |
886 | CutEdge(E, theparam, E1, E2, exp.CurrentVertex()); |
887 | Edges(ii) = E1; |
888 | ii++; |
889 | Edges(ii) = E2; |
890 | rangdeb = ii; |
891 | } |
892 | else { |
893 | Edges(ii) = E; |
894 | } |
895 | if (!NewVertex && V.IsSame(exp.CurrentVertex())) { |
896 | rangdeb = ii; |
897 | } |
898 | } |
899 | if (rangdeb == 0) rangdeb = NbEdges; |
900 | |
901 | // Calcul du sens de parcourt |
902 | E = TopoDS::Edge(Edges(rangdeb)); |
903 | if (!NewVertex) { |
904 | // theparam = BT.Parameter(V, E); |
905 | theparam = BRep_Tool::Parameter(V, E); |
906 | } |
907 | BRepAdaptor_Curve AC(E); |
908 | gp_Pnt Pe; |
909 | gp_Vec Ve; |
910 | AC.D1(theparam, Pe, Ve); |
911 | if (E.Orientation()==TopAbs_REVERSED) { |
912 | Ve *= -1; |
913 | } |
914 | angle = Ve.Angle(Dir); |
915 | if (angle > PI) angle = 2*PI - angle; |
916 | forward = (angle <= PI/2); |
917 | |
918 | // Reconstruction |
919 | MakeWire( Edges, rangdeb, forward, W); |
920 | W.Closed(Standard_True); |
921 | } |
922 | |
923 | |
924 | |
925 | //======================================================================= |
926 | //function : ComputeACR |
927 | //purpose : |
928 | //======================================================================= |
929 | |
930 | void BRepFill::ComputeACR(const TopoDS_Wire& wire, |
931 | TColStd_Array1OfReal& ACR) |
932 | { |
933 | // calcul des abscisses curvilignes reduites et de la longueur du wire |
934 | BRepTools_WireExplorer anExp; |
935 | Standard_Integer nbEdges=0, i; |
936 | |
937 | // longueurs cumulees |
938 | ACR.Init(0); |
939 | for(anExp.Init(wire); anExp.More(); anExp.Next()) { |
940 | nbEdges++; |
941 | TopoDS_Edge Ecur = TopoDS::Edge(anExp.Current()); |
942 | ACR(nbEdges) = ACR(nbEdges-1); |
943 | if (!BRep_Tool::Degenerated(Ecur)) { |
944 | BRepAdaptor_Curve anEcur(Ecur); |
945 | ACR(nbEdges) += GCPnts_AbscissaPoint::Length(anEcur); |
946 | } |
947 | } |
948 | |
949 | // longueur totale du wire |
950 | ACR(0) = ACR(nbEdges); |
951 | |
952 | // abscisses curvilignes reduites |
953 | if (ACR(0)>Precision::Confusion()) { |
954 | for (i=1; i<=nbEdges; i++) { |
955 | ACR(i) /= ACR(0); |
956 | } |
957 | } |
958 | else { |
959 | // wire ponctuel |
960 | ACR(nbEdges) = 1; |
961 | } |
962 | |
963 | } |
964 | |
965 | //======================================================================= |
966 | //function : InsertACR |
967 | //purpose : |
968 | //======================================================================= |
969 | |
970 | TopoDS_Wire BRepFill::InsertACR(const TopoDS_Wire& wire, |
971 | const TColStd_Array1OfReal& ACRcuts, |
972 | const Standard_Real prec) |
973 | { |
974 | // calcul des ACR du wire a decouper |
975 | BRepTools_WireExplorer anExp; |
976 | Standard_Integer nbEdges=0; |
977 | for(anExp.Init(wire); anExp.More(); anExp.Next()) { |
978 | nbEdges++; |
979 | } |
980 | TColStd_Array1OfReal ACRwire(0,nbEdges); |
981 | ComputeACR(wire, ACRwire); |
982 | |
983 | Standard_Integer i, j, nmax=ACRcuts.Length(); |
984 | TColStd_Array1OfReal paradec(1,nmax); |
985 | BRepLib_MakeWire MW; |
986 | |
987 | Standard_Real t0,t1=0; |
988 | nbEdges=0; |
989 | |
990 | // traitement edge par edge |
991 | for(anExp.Init(wire); anExp.More(); anExp.Next()) { |
992 | nbEdges++; |
993 | t0 = t1; |
994 | t1 = ACRwire(nbEdges); |
995 | |
996 | // parametres de decoupe sur cette edge |
997 | Standard_Integer ndec=0; |
998 | for (i=1; i<=ACRcuts.Length(); i++ ) { |
999 | if (t0+prec<ACRcuts(i) && ACRcuts(i)<t1-prec) { |
1000 | ndec++; |
1001 | paradec(ndec) = ACRcuts(i); |
1002 | } |
1003 | } |
1004 | |
1005 | TopoDS_Edge E = anExp.Current(); |
1006 | TopoDS_Vertex V = anExp.CurrentVertex(); |
1007 | |
1008 | if (ndec==0 || BRep_Tool::Degenerated(E)) { |
1009 | // on copie l'edge |
1010 | MW.Add(E); |
1011 | } |
1012 | else { |
1013 | // il faut couper l'edge |
1014 | // en respectant le sens de parcours du wire |
1015 | Standard_Boolean SO = (V.IsSame(TopExp::FirstVertex(E))); |
1016 | TopTools_SequenceOfShape SE; |
1017 | SE.Clear(); |
1018 | TColStd_SequenceOfReal SR; |
1019 | SR.Clear(); |
1020 | // le wire est toujours FORWARD |
1021 | // il faut modifier le parametre de decoupe si l'edge est REVERSED |
1022 | if (E.Orientation() == TopAbs_FORWARD) { |
1023 | for (j=1; j<=ndec; j++) SR.Append(paradec(j)); |
1024 | } |
1025 | else { |
1026 | for (j=1; j<=ndec; j++) SR.Append(t0+t1-paradec(ndec+1-j)); |
1027 | } |
1028 | TrimEdge(E,SR,t0,t1,SO,SE); |
1029 | for (j=1; j<=SE.Length(); j++) { |
1030 | MW.Add(TopoDS::Edge(SE.Value(j))); |
1031 | } |
1032 | } |
1033 | } |
1034 | |
1035 | // resultat |
1036 | TopAbs_Orientation Orien = wire.Orientation(); |
1037 | TopoDS_Shape aLocalShape = MW.Wire(); |
1038 | aLocalShape.Orientation(Orien); |
1039 | TopoDS_Wire wres = TopoDS::Wire(aLocalShape); |
1040 | // TopoDS_Wire wres = TopoDS::Wire(MW.Wire().Oriented(Orien)); |
1041 | return wres; |
1042 | } |
1043 | |
1044 | |
1045 | |
1046 | |
1047 | |
1048 | |
1049 | |
1050 | |
1051 | |
1052 | |
1053 | |
1054 | |
1055 | |
1056 | |
1057 | |
1058 | |
1059 | |
1060 | |
1061 | |
1062 | |
1063 | |
1064 | |
1065 | |
1066 | |
1067 | |
1068 | |
1069 | |
1070 | |
1071 | |
1072 | |
1073 | |
1074 | |
1075 | |
1076 | |
1077 | |
1078 | |
1079 | |
1080 | |
1081 | |
1082 | |
1083 | |
1084 | |
1085 | |
1086 | |