Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1995-03-29 |
2 | // Created by: Frederic MAUPAS | |
3 | // Copyright (c) 1995-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 | // gka 21.08.98 PRO7656 |
18 | // gka 15.12.98 UKI60591 #1274560 | |
19 | //pdn 18.12.98 to keep pcurves | |
20 | //:o0 abv 16.02.99: POLYLINE allowed as 3d curve of edge | |
21 | //: abv 07.04.99: S4136: improve tolerance management and dealing with pcurves | |
22 | // rln 02.06.99 removing #include <StepToTopoDS_DegeneratedTool.hxx> | |
23 | // smh 31.01.01 BUC60810 : IsNull protection | |
24 | #include <StepToTopoDS_TranslateEdgeLoop.ixx> | |
25 | ||
26 | #include <StepToTopoDS.hxx> | |
27 | #include <StepToTopoDS_TranslateVertex.hxx> | |
28 | #include <StepToTopoDS_TranslateEdge.hxx> | |
29 | #include <StepToTopoDS_GeometricTool.hxx> | |
30 | #include <ShapeAnalysis_Curve.hxx> | |
31 | #include <StepToGeom_MakeCurve2d.hxx> | |
32 | #include <StepToGeom_MakeCurve.hxx> | |
33 | ||
34 | #include <Geom_RectangularTrimmedSurface.hxx> | |
35 | ||
36 | #include <StepShape_EdgeLoop.hxx> | |
37 | #include <StepShape_Edge.hxx> | |
38 | #include <StepShape_OrientedEdge.hxx> | |
39 | #include <StepGeom_Curve.hxx> | |
40 | #include <StepShape_EdgeCurve.hxx> | |
41 | #include <StepGeom_Pcurve.hxx> | |
42 | //#include <StepGeom_Polyline.hxx> | |
43 | #include <StepGeom_SurfaceCurve.hxx> | |
44 | #include <StepRepr_DefinitionalRepresentation.hxx> | |
45 | #include <StepGeom_PcurveOrSurface.hxx> | |
46 | ||
47 | #include <BRep_Builder.hxx> | |
48 | #include <BRep_Tool.hxx> | |
49 | ||
50 | #include <TopoDS.hxx> | |
51 | #include <TopoDS_Wire.hxx> | |
52 | #include <TopoDS_Edge.hxx> | |
53 | #include <TopoDS_Vertex.hxx> | |
54 | ||
55 | #include <BRep_TEdge.hxx> | |
56 | #include <BRep_CurveRepresentation.hxx> | |
57 | #include <BRep_ListOfCurveRepresentation.hxx> | |
58 | #include <BRep_ListIteratorOfListOfCurveRepresentation.hxx> | |
59 | ||
60 | #include <TopExp_Explorer.hxx> | |
61 | #include <TopExp.hxx> | |
62 | ||
63 | #include <TopLoc_Location.hxx> | |
64 | #include <TopAbs.hxx> | |
65 | ||
66 | #include <Geom_Surface.hxx> | |
67 | #include <Geom_Plane.hxx> | |
68 | #include <Geom_Curve.hxx> | |
69 | ||
70 | #include <Geom2d_Curve.hxx> | |
71 | #include <Geom2d_BoundedCurve.hxx> | |
72 | #include <Geom2d_Line.hxx> | |
73 | ||
74 | #include <gp_Pnt.hxx> | |
75 | #include <gp_Pnt2d.hxx> | |
76 | ||
77 | #include <Precision.hxx> | |
78 | #include <Interface_Static.hxx> | |
79 | #include <Transfer_TransientProcess.hxx> | |
80 | #include <TopoDS_Iterator.hxx> | |
81 | #include <ShapeFix_EdgeProjAux.hxx> | |
82 | #include <ShapeAnalysis_Edge.hxx> | |
83 | #include <ShapeExtend_WireData.hxx> | |
84 | #include <ShapeBuild_Edge.hxx> | |
85 | ||
86 | #include <ShapeAlgo.hxx> | |
87 | #include <ShapeAlgo_AlgoContainer.hxx> | |
88 | #include <ShapeAlgo_ToolContainer.hxx> | |
89 | #include <XSAlgo.hxx> | |
90 | #include <XSAlgo_AlgoContainer.hxx> | |
bcf045cf | 91 | #include <ElCLib.hxx> |
d088c9c2 | 92 | #include <Standard_ErrorHandler.hxx> |
7fd59977 | 93 | |
94 | // ============================================================================ | |
95 | // Method : RemoveSinglePCurve | |
96 | // Purpose : | |
97 | // ============================================================================ | |
98 | ||
99 | static void RemoveSinglePCurve (const TopoDS_Edge& aEdge, const TopoDS_Face& aFace) | |
100 | { | |
101 | ShapeBuild_Edge().RemovePCurve (aEdge, aFace); | |
102 | } | |
103 | ||
104 | // ============================================================================ | |
105 | // Method : RemovePCurves | |
106 | // Purpose : | |
107 | // ============================================================================ | |
108 | ||
109 | static void RemovePCurves(const TopoDS_Wire& aWire, const TopoDS_Face& aFace) | |
110 | { | |
111 | TopExp_Explorer EdgeExp(aWire, TopAbs_EDGE); | |
112 | while (EdgeExp.More()) { | |
113 | const TopoDS_Edge& myEdge = TopoDS::Edge(EdgeExp.Current()); | |
114 | RemoveSinglePCurve(myEdge,aFace); | |
115 | EdgeExp.Next(); | |
116 | } | |
117 | } | |
118 | ||
119 | // ============================================================================ | |
120 | // Method : CheckPCurves | |
121 | // Purpose : Checks the pcurves topological trimming parameter consistency | |
122 | // and deviation between 2D ans 3D | |
123 | // ============================================================================ | |
124 | ||
125 | static void CheckPCurves (TopoDS_Wire& aWire, const TopoDS_Face& aFace, | |
126 | const Standard_Boolean isPlane,const Standard_Real preci ) | |
127 | { | |
128 | if (isPlane) { RemovePCurves (aWire,aFace);return; } | |
129 | BRep_Builder B; | |
130 | Standard_Real w1, w2, cf, cl; | |
131 | Handle(Geom_Surface) mySurf = BRep_Tool::Surface(aFace); | |
132 | ||
133 | Handle(ShapeExtend_WireData) sbwd = new ShapeExtend_WireData ( aWire ); | |
134 | for (Standard_Integer i = 1; i <= sbwd->NbEdges(); i++) { | |
135 | const TopoDS_Edge& myEdge = sbwd->Edge(i); | |
136 | // B.SameRange( myEdge, Standard_True ); | |
137 | // B.SameParameter ( myEdge, Standard_True ); | |
138 | ||
139 | // First Check : 2D Parameters on Edge : | |
140 | // Case 1 : w1 == w2 illegal => Drop the PCurve | |
141 | // Case 2 : on bounded curve w1 < FirstParameter => w1 = FirstParameter | |
142 | // w2 > LastParameter => w2 = LastParameter | |
143 | ||
144 | Handle(Geom2d_Curve) thePC; | |
145 | ShapeAnalysis_Edge sae; | |
146 | if (!sae.PCurve (myEdge, aFace, thePC, w1, w2, Standard_False )) { | |
147 | continue; | |
148 | } | |
149 | cf = thePC->FirstParameter(); | |
150 | cl = thePC->LastParameter(); | |
151 | ||
152 | if (w1 == w2) { | |
153 | RemoveSinglePCurve(myEdge,aFace); | |
0797d9d3 | 154 | #ifdef OCCT_DEBUG |
7fd59977 | 155 | cout<<"Removing pcuve w1=w2"<<endl; |
156 | #endif | |
157 | continue; | |
158 | } | |
159 | ||
160 | if (w1 < cf) { | |
161 | B.Range(myEdge, aFace, cf, w2); | |
162 | w1 = cf; | |
163 | } | |
164 | if (w2 > cl) { | |
165 | B.Range(myEdge, aFace, w1, cl); | |
166 | w2 = cf; | |
167 | } | |
bcf045cf | 168 | |
169 | if (w1 > w2 && mySurf->IsUPeriodic()) | |
170 | { | |
171 | Standard_Real u1,u2,v1,v2; | |
172 | mySurf->Bounds(u1,u2,v1,v2); | |
173 | ElCLib::AdjustPeriodic(u1, u2, | |
174 | Min(Abs(w2-w1)/2,Precision::PConfusion()), | |
175 | w1, w2); | |
176 | B.Range(myEdge, aFace, w1, w2); | |
177 | } | |
178 | ||
7fd59977 | 179 | |
180 | // advanced check | |
181 | XSAlgo::AlgoContainer()->CheckPCurve (myEdge, aFace, preci, sbwd->IsSeam(i) ); | |
182 | } | |
183 | } | |
184 | ||
185 | // ============================================================================ | |
186 | // Method : StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop | |
187 | // Purpose : Empty Constructor | |
188 | // ============================================================================ | |
189 | ||
190 | StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop() | |
191 | { | |
192 | done = Standard_False; | |
193 | } | |
194 | ||
195 | // ============================================================================ | |
196 | // Method : StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop | |
197 | // Purpose : Constructor with a FaceSurface and a Tool | |
198 | // ============================================================================ | |
199 | ||
200 | StepToTopoDS_TranslateEdgeLoop::StepToTopoDS_TranslateEdgeLoop(const Handle(StepShape_FaceBound)& FB, | |
201 | const TopoDS_Face& Face, | |
202 | const Handle(Geom_Surface)& GeomSurf, | |
203 | const Handle(StepGeom_Surface)& StepSurf, | |
204 | const Standard_Boolean sameSense, | |
205 | StepToTopoDS_Tool& T, | |
206 | StepToTopoDS_NMTool& NMTool) { | |
207 | Init(FB, Face, GeomSurf, StepSurf, sameSense, T, NMTool); | |
208 | } | |
209 | ||
210 | // ============================================================================ | |
211 | // Method : Init | |
212 | // Purpose : Init with a EdgeLoop and a Tool | |
213 | // ============================================================================ | |
214 | ||
215 | void StepToTopoDS_TranslateEdgeLoop::Init(const Handle(StepShape_FaceBound)& FaceBound, | |
216 | const TopoDS_Face& Face, | |
217 | const Handle(Geom_Surface)& GeomSurf, | |
218 | const Handle(StepGeom_Surface)& StepSurf, | |
219 | const Standard_Boolean sameSense, | |
220 | StepToTopoDS_Tool& aTool, | |
221 | StepToTopoDS_NMTool& NMTool) { | |
222 | done = Standard_True; | |
223 | Handle(StepShape_EdgeLoop) EL = | |
224 | Handle(StepShape_EdgeLoop)::DownCast(FaceBound->Bound()); | |
225 | ||
226 | if (aTool.IsBound(EL)) { | |
227 | myResult = TopoDS::Wire(aTool.Find(EL)); | |
228 | myError = StepToTopoDS_TranslateEdgeLoopDone; | |
229 | done = Standard_True; | |
230 | return; | |
231 | } | |
232 | Standard_Integer modepcurve = Interface_Static::IVal("read.surfacecurve.mode"); | |
233 | // 0,1 : suivre le code, 2 : ne prendre que pcurve, 3 : ne prendre que C3D | |
234 | ||
235 | BRep_Builder B; | |
236 | Handle(Transfer_TransientProcess) TP = aTool.TransientProcess(); | |
237 | ||
238 | Standard_Real preci = Precision(); | |
239 | TopoDS_Wire W; | |
240 | TopoDS_Edge E; | |
241 | TopoDS_Vertex V; | |
242 | ||
243 | // Standard_Real U1,U2, U1a, U1b, U2a, U2b; | |
244 | ||
245 | Standard_Boolean isSeam, isLikeSeam; | |
246 | ||
247 | Handle(StepShape_Edge) StepEdge, StepEdge1; | |
248 | Handle(StepShape_OrientedEdge) OrEdge1, OrEdge2; | |
249 | Handle(StepGeom_Curve) StepCurve, StepCurve1, StepCurve2; | |
250 | // Handle(StepGeom_Pcurve) StepPCurve, StepPCurve1, StepPCurve2; | |
251 | Handle(StepRepr_DefinitionalRepresentation) DRI, Dri1, Dri2; | |
252 | ||
253 | Handle(Geom2d_Curve) C2d, C2d1, C2d2, WhichC2d1, WhichC2d2; | |
254 | // unused gp_Pnt Pdeb, Pmil, Pfin, pV1, pV2; | |
255 | ||
256 | TopoDS_Edge suspectE; //:f1, degEdge; | |
257 | ||
258 | Standard_Integer j, NbEdge = EL->NbEdgeList(); | |
259 | if( NbEdge == 0) { | |
260 | TP->AddWarning(EL,"Wire not done. EdgeLoop does not contain edges."); | |
261 | done = Standard_False; | |
262 | return; | |
263 | } | |
264 | // PTV 16.09.2000 | |
265 | // default value set as Standard_True (if not correct see logic of algorithm). | |
266 | Standard_Boolean hasPcurve = Standard_True; | |
267 | Standard_Boolean isPlane = GeomSurf->IsKind(STANDARD_TYPE(Geom_Plane)); | |
268 | Handle(Geom_Surface) ConvSurf = GeomSurf; | |
269 | if (GeomSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) { | |
270 | Handle(Geom_RectangularTrimmedSurface) theRTS = | |
271 | Handle(Geom_RectangularTrimmedSurface)::DownCast(GeomSurf); | |
272 | ConvSurf = theRTS->BasisSurface(); | |
273 | } | |
274 | ||
275 | aTool.ComputePCurve(Standard_False); | |
276 | ||
277 | // What is the Wire Orientation | |
278 | Standard_Boolean ForwardWire = FaceBound->Orientation(); | |
279 | ||
280 | // --- Initialize target Wire --- | |
281 | ||
282 | B.MakeWire(W); | |
283 | ||
284 | // Standard_Integer lastpcurve = 0; | |
285 | ||
286 | // ----------------------------------------------- | |
287 | // Preparation : Make Vertices + Curves3d | |
288 | // Hence, a closed curve limited by distinct vertices | |
289 | // will give a unique vertex (if same coords) | |
290 | // | |
291 | // In addition : detect shared PCurve (cf SYRKO) | |
292 | // This case may not be processed, PCurves has to be recomputed from scratch | |
293 | // ----------------------------------------------- | |
294 | // Standard_Integer theSame = 1; //gka 15.12.98 | |
295 | ||
296 | for (j=1; j<=NbEdge; j++ ) { | |
297 | OrEdge1 = EL->EdgeListValue(j); | |
298 | StepEdge = OrEdge1->EdgeElement(); | |
299 | // if(j>1 && StepEdge == StepEdge1) theSame++; //gka 15.12.98 | |
300 | StepEdge1 = StepEdge; // | |
301 | Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(StepEdge); | |
302 | Handle(StepGeom_Curve) C = EC->EdgeGeometry(); | |
2a141d40 | 303 | if (!C.IsNull()){ |
304 | if (C->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve))) { | |
305 | Handle(StepGeom_SurfaceCurve) Sc = Handle(StepGeom_SurfaceCurve)::DownCast(C); | |
306 | C = Sc->Curve3d(); | |
7fd59977 | 307 | // if (modepcurve != 3) { |
308 | // lastpcurve = StepToTopoDS_GeometricTool::PCurve (Sc,StepSurf,StepPCurve1); | |
309 | // if (StepPCurve1 == StepPCurve) modepcurve = -1; | |
310 | // StepPCurve = StepPCurve1; | |
311 | // } | |
2a141d40 | 312 | } |
7fd59977 | 313 | } |
314 | //// else if (C->IsKind(STANDARD_TYPE(StepGeom_Polyline))) { } | |
315 | // else if (C->IsKind(STANDARD_TYPE(StepGeom_Pcurve))) { | |
316 | // if (modepcurve != 3) { | |
317 | // if (C == StepPCurve) modepcurve = -1; | |
318 | // StepPCurve = Handle(StepGeom_Pcurve)::DownCast(C); | |
319 | // } | |
320 | // } | |
321 | Handle(Geom_Curve) C1; | |
322 | if (!C.IsNull()) { | |
d088c9c2 | 323 | try |
324 | { | |
325 | OCC_CATCH_SIGNALS | |
326 | C1 = Handle(Geom_Curve)::DownCast (TP->FindTransient(C)); | |
327 | if (C1.IsNull()) { | |
328 | if (StepToGeom_MakeCurve::Convert(C,C1)) | |
329 | TP->BindTransient (C,C1); | |
330 | else | |
331 | TP->AddWarning(C,"Could not convert a curve. Curve definition is incorrect"); | |
332 | } | |
333 | } | |
334 | catch (Standard_Failure) | |
335 | { | |
336 | TP->AddFail(C,"Exeption was raised. Curve geometry definition is incorrect"); | |
337 | #ifdef OCCT_DEBUG | |
338 | cout << "Warning: StepToTopoDS_TranslateEdgeLoop: Exception: "; | |
339 | Standard_Failure::Caught()->Print(cout); cout << endl; | |
340 | #endif | |
7fd59977 | 341 | } |
342 | } | |
343 | ||
344 | Handle(StepShape_Vertex) Vstart, Vend; | |
345 | if (EC->SameSense()) { | |
346 | Vstart = EC->EdgeStart(); | |
347 | Vend = EC->EdgeEnd(); | |
348 | } | |
349 | else { | |
350 | Vend = EC->EdgeStart(); | |
351 | Vstart = EC->EdgeEnd(); | |
352 | } | |
353 | ||
354 | Standard_Boolean istV = aTool.IsBound(Vstart); | |
355 | Standard_Boolean iseV = aTool.IsBound(Vend); | |
356 | TopoDS_Vertex V1, V2; | |
357 | StepToTopoDS_TranslateVertex myTranVertex1(Vstart, aTool, NMTool); | |
358 | StepToTopoDS_TranslateVertex myTranVertex2(Vend, aTool, NMTool); | |
359 | ||
360 | if (myTranVertex1.IsDone()) { | |
361 | V1 = TopoDS::Vertex(myTranVertex1.Value()); | |
362 | } | |
363 | // if (Vend == Vstart) { cas normal deja assure par aTool | |
364 | // aTool.Bind (Vend,V1); | |
365 | // } | |
366 | // else | |
367 | if (myTranVertex2.IsDone()) { | |
368 | V2 = TopoDS::Vertex(myTranVertex2.Value()); | |
369 | gp_Pnt p1 = BRep_Tool::Pnt(V1); | |
370 | gp_Pnt p2 = BRep_Tool::Pnt(V2); | |
371 | if (p1.Distance(p2) <= Precision::Confusion() ) { //:S4136: preci) { | |
372 | Standard_Boolean Fixed = Standard_True; | |
373 | if(!iseV) aTool.Bind(Vend,V1); //gka 21.08.1998 bug PRO7656 | |
374 | else if(!istV) aTool.Bind (Vstart,V2); | |
375 | else aTool.Bind (Vend,V1); | |
376 | //Fixed = Standard_False; | |
377 | //aTool.Bind (Vend,V1); | |
378 | if (!C1.IsNull() && !C1->IsClosed() && Fixed) | |
379 | TP->AddWarning(EL->EdgeListValue(j), | |
380 | "Vertex of same coordinates, set confused"); | |
381 | } | |
382 | } | |
383 | } | |
384 | // if (NbEdge!=1 && theSame == NbEdge) { | |
385 | // TP->AddWarning(EL,"Wire was ignored. All edges are the same."); | |
386 | // done = Standard_False; | |
387 | // return; | |
388 | // } | |
389 | // Fixed=Standard_True; | |
390 | // if (modepcurve == -1) { | |
391 | // modepcurve = 3; | |
392 | // TP->AddWarning(EL,"Shared Pcurve not allowed, Pcurves are recomputed"); | |
393 | // } | |
394 | ||
395 | //:f6 abv 29 Apr 98: BUC50070 #3815: make sure that each two edges are | |
396 | // connected by the same vertex; else check that vertices confuse | |
397 | // and make it be one vertex | |
398 | // NOTE: this is done only for the case if at least one of edges | |
399 | // was not yet translated; else nothing will help | |
400 | for (j=1; j<=NbEdge; j++ ) { | |
401 | OrEdge1 = EL->EdgeListValue ( j ); | |
402 | OrEdge2 = EL->EdgeListValue ( j < NbEdge ? j + 1 : 1 ); | |
403 | Handle(StepShape_EdgeCurve) EC1 = | |
404 | Handle(StepShape_EdgeCurve)::DownCast ( OrEdge1->EdgeElement() ); | |
405 | Handle(StepShape_EdgeCurve) EC2 = | |
406 | Handle(StepShape_EdgeCurve)::DownCast ( OrEdge2->EdgeElement() ); | |
407 | ||
408 | Handle(StepShape_Vertex) Vs1, Vs2,Vs11,Vs22; | |
409 | Vs1 = ( OrEdge1->Orientation() ? EC1->EdgeEnd() : EC1->EdgeStart() ); | |
410 | Vs2 = ( OrEdge2->Orientation() ? EC2->EdgeStart() : EC2->EdgeEnd() ); | |
411 | ||
412 | Vs11 = ( OrEdge1->Orientation() ? EC1->EdgeStart() : EC1->EdgeEnd()); | |
413 | Vs22 = ( OrEdge2->Orientation() ? EC2->EdgeEnd() : EC2->EdgeStart() ); | |
414 | ||
415 | if((Vs1 == Vs2) || (Vs1 == Vs22) || (Vs2 == Vs11) || (Vs22 == Vs11)) continue; | |
416 | //?? if ( Vs1.IsSame(Vs2) ) continue; // OK | |
417 | ||
418 | StepToTopoDS_TranslateVertex myTranVertex1 (Vs1, aTool, NMTool); | |
419 | StepToTopoDS_TranslateVertex myTranVertex2 (Vs2, aTool, NMTool); | |
420 | ||
421 | TopoDS_Vertex V1, V2; | |
422 | if ( myTranVertex1.IsDone() ) | |
423 | V1 = TopoDS::Vertex ( myTranVertex1.Value() ); | |
424 | if ( myTranVertex2.IsDone() ) | |
425 | V2 = TopoDS::Vertex ( myTranVertex2.Value() ); | |
426 | if ( V1.IsNull() || V2.IsNull() ) continue; // not treated | |
427 | if ( V1.IsSame(V2) ) continue; // OK | |
428 | ||
429 | gp_Pnt p1 = BRep_Tool::Pnt(V1); | |
430 | gp_Pnt p2 = BRep_Tool::Pnt(V2); | |
431 | Standard_Boolean locFixed = Standard_True; | |
432 | if (p1.Distance(p2) <= preci) { | |
433 | if ( ! aTool.IsBound ( EC1 ) ) aTool.Bind ( Vs1, V2 ); | |
434 | else if ( ! aTool.IsBound ( EC2 ) ) aTool.Bind ( Vs2, V1 ); | |
435 | else locFixed = Standard_False; | |
436 | } | |
437 | else locFixed = Standard_False; | |
438 | if ( locFixed ) TP->AddWarning(EL,"Adjacent edges do not have common vertex; set confused"); | |
439 | else TP->AddWarning(EL,"Adjacent edges are not connected"); | |
440 | } | |
441 | ||
442 | // ----------------------------------------------- | |
443 | // Iteration on each Oriented Edge of the EdgeLoop | |
444 | // ----------------------------------------------- | |
445 | ||
446 | for (j=1; j<=NbEdge; j++ ) { | |
447 | ||
448 | Standard_Boolean ThereIsLikeSeam = Standard_False; | |
449 | ||
0797d9d3 | 450 | #ifdef OCCT_DEBUG |
7fd59977 | 451 | cout << " Processing Edge :" << j << endl; |
452 | #endif | |
453 | ||
454 | OrEdge1 = EL->EdgeListValue(j); | |
455 | StepEdge = OrEdge1->EdgeElement(); | |
456 | Handle(StepShape_EdgeCurve) EC = Handle(StepShape_EdgeCurve)::DownCast(StepEdge); | |
457 | ||
458 | // ---------------- | |
459 | // Map the StepEdge | |
460 | // ---------------- | |
461 | ||
462 | StepToTopoDS_TranslateEdge myTranEdge; | |
463 | ||
464 | myTranEdge.SetPrecision(preci); | |
465 | myTranEdge.SetMaxTol(MaxTol()); | |
466 | myTranEdge.Init(OrEdge1, aTool, NMTool); | |
467 | ||
468 | if (myTranEdge.IsDone()) { | |
469 | ||
470 | E = TopoDS::Edge(myTranEdge.Value()); | |
471 | if (E.IsNull()) continue; // NULL, on saute | |
472 | ||
473 | Handle(StepGeom_Curve) C = EC->EdgeGeometry(); | |
474 | ||
475 | if (OrEdge1->Orientation() && EC->SameSense()) | |
476 | E.Orientation(TopAbs_FORWARD); | |
477 | else if (!OrEdge1->Orientation() && !EC->SameSense()) | |
478 | E.Orientation(TopAbs_FORWARD); | |
479 | else E.Orientation(TopAbs_REVERSED); | |
480 | ||
481 | isSeam = isLikeSeam = Standard_False; | |
482 | ||
483 | // ------------------------------------------ | |
484 | // Map the StepEdge parametric representation | |
485 | // ------------------------------------------ | |
486 | ||
487 | // -------------------------------------------- | |
488 | // CASE 1 : The Edge Geometry is of Pcurve Type | |
489 | // -------------------------------------------- | |
2a141d40 | 490 | if (C.IsNull()) |
491 | { | |
492 | aTool.ComputePCurve(Standard_True); | |
493 | hasPcurve = Standard_False; | |
494 | } | |
495 | else if (C->IsKind(STANDARD_TYPE(StepGeom_Pcurve))) { | |
7fd59977 | 496 | Handle(StepGeom_Pcurve) StepPCurve = Handle(StepGeom_Pcurve)::DownCast(C); |
497 | C2d = myTranEdge.MakePCurve (StepPCurve,ConvSurf); | |
498 | // -- Statistics -- | |
499 | aTool.AddContinuity (C2d); | |
500 | } | |
501 | ||
502 | // ----------------------------------------- | |
503 | // CASE 2 : The curve is a SurfaceCurve i.e. | |
504 | // - a 3D Curve (mandatory) | |
505 | // - 2 PCurveOrSurface | |
506 | // If modepcurve = 3, PCurve are ignored here | |
507 | // ----------------------------------------- | |
508 | ||
509 | else if (modepcurve == 3) { | |
510 | aTool.ComputePCurve(Standard_True); | |
511 | hasPcurve = Standard_False; | |
512 | } | |
513 | else if (C->IsKind(STANDARD_TYPE(StepGeom_SurfaceCurve)) ) { | |
514 | // recouvre les cas SeamCurve et IntersectionCurve | |
515 | ||
516 | Handle(StepGeom_SurfaceCurve) SurfCurve = | |
517 | Handle(StepGeom_SurfaceCurve)::DownCast(C); | |
518 | ||
519 | Handle(StepGeom_Pcurve) StepPCurve, StepPCurve1, StepPCurve2; | |
520 | Standard_Integer lastpcurve = StepToTopoDS_GeometricTool::PCurve(SurfCurve,StepSurf,StepPCurve,0); | |
521 | hasPcurve = !StepPCurve.IsNull(); | |
522 | ||
523 | // De toute facon, on recalcule | |
524 | ||
525 | if (isPlane) hasPcurve = Standard_False; | |
526 | ||
527 | // ------------------------------------------- | |
528 | // --- Special Mapping Cases : --- | |
529 | // --- the SurfaceCurve is a SeamCurve --- | |
530 | // --- or is like a seam curve --- | |
531 | // --- (see CATIA cylinder) --- | |
532 | // ------------------------------------------- | |
533 | isLikeSeam = StepToTopoDS_GeometricTool::IsLikeSeam(SurfCurve,StepSurf,StepEdge,EL); | |
534 | ||
535 | isSeam = StepToTopoDS_GeometricTool::IsSeamCurve(SurfCurve, StepSurf,StepEdge, EL); | |
536 | ||
537 | if (isSeam || isLikeSeam) { | |
538 | // isLikeSeam = Two faces on the same Surface | |
539 | StepPCurve1 = SurfCurve->AssociatedGeometryValue(1).Pcurve(); | |
540 | StepPCurve2 = SurfCurve->AssociatedGeometryValue(2).Pcurve(); | |
541 | if (StepPCurve1.IsNull() || StepPCurve2.IsNull()) hasPcurve = Standard_False; //smh : BUC60810 | |
542 | else { | |
543 | C2d1 = myTranEdge.MakePCurve (StepPCurve1,ConvSurf); | |
544 | C2d2 = myTranEdge.MakePCurve (StepPCurve2,ConvSurf); | |
545 | hasPcurve = (!C2d1.IsNull() && !C2d2.IsNull()); | |
546 | } | |
547 | ||
548 | if (isLikeSeam) { | |
549 | suspectE = E; | |
550 | ThereIsLikeSeam = Standard_True; | |
551 | hasPcurve = Standard_True; | |
552 | } | |
553 | } | |
554 | else if (hasPcurve) { | |
555 | // GeometricTool : Pcurve a retourne StepPCurve | |
556 | while (lastpcurve > 0) { | |
557 | C2d1 = myTranEdge.MakePCurve (StepPCurve,ConvSurf); | |
558 | if (C2d1.IsNull()) { | |
559 | hasPcurve = Standard_False; | |
560 | break; | |
561 | } | |
562 | else C2d = C2d1; | |
563 | lastpcurve = StepToTopoDS_GeometricTool::PCurve(SurfCurve,StepSurf,StepPCurve,lastpcurve); | |
564 | // -- Statistics -- | |
565 | aTool.AddContinuity (C2d); | |
566 | } | |
567 | } | |
568 | if (!hasPcurve) { | |
569 | // The edge geometry has no 2D representation | |
570 | aTool.ComputePCurve(Standard_True); | |
571 | } | |
572 | } | |
573 | ||
574 | // ---------------------------------------------------------- | |
575 | // CASE 3 : The EdgeCurve Geometry is not a Pcurve | |
576 | // nor a SurfaceCurve (i.e. it is a single 3D curve) | |
577 | // ---------------------------------------------------------- | |
578 | ||
579 | else { | |
580 | aTool.ComputePCurve(Standard_True); | |
581 | hasPcurve = Standard_False; | |
582 | } | |
583 | ||
584 | // ---------------------------------- | |
585 | // update the edge with the pcurve(s) | |
586 | // ---------------------------------- | |
587 | ||
588 | if (hasPcurve && (isSeam || ThereIsLikeSeam)) { | |
589 | ||
590 | // ----------------------------------------------------------- | |
591 | // The Edge is a Seam Edge : The pcurve wich is FORWARD has to | |
592 | // be identified | |
593 | // ----------------------------------------------------------- | |
594 | ||
595 | if ((!C2d1.IsNull()) && (!C2d2.IsNull())) { | |
596 | TopAbs_Orientation CumulO, EdgeO, WireO, FaceO; | |
597 | EdgeO = E.Orientation(); | |
598 | if (ForwardWire) WireO = TopAbs_FORWARD; | |
599 | else WireO = TopAbs_REVERSED; | |
600 | if (sameSense) FaceO = TopAbs_FORWARD; | |
601 | else FaceO = TopAbs_REVERSED; | |
602 | ||
603 | CumulO = TopAbs::Compose(EdgeO, WireO); | |
604 | CumulO = TopAbs::Compose(CumulO, FaceO); | |
605 | ||
606 | Standard_Boolean ForwardEdge = (CumulO == TopAbs_FORWARD); | |
607 | ||
608 | // if(!ThereIsLikeSeam) ForwardEdge = Standard_True; | |
609 | Standard_Integer forwardPC = | |
610 | ShapeAnalysis_Curve().SelectForwardSeam (C2d1,C2d2); | |
611 | if (forwardPC == 0) { | |
612 | TP->AddFail(StepEdge," Seam curve not mapped"); | |
613 | done = Standard_False; | |
614 | myError = StepToTopoDS_TranslateEdgeLoopOther; | |
615 | continue; | |
616 | } | |
617 | else if (!ForwardEdge) forwardPC = 3 - forwardPC; // inverser 1-2 | |
618 | ||
619 | if (forwardPC == 1) { | |
620 | if(isSeam) { | |
621 | // When the edge is a Seam, it is better to find the topological | |
622 | // trimming right now. | |
623 | // Remarque : pour bien faire, il faudrait, si necessaire, recalculer | |
624 | // les trois courbes de maniere a ce qu`elles soient | |
625 | // immediatement Same Range et Same Parameter. | |
626 | B.UpdateEdge(E, C2d1, C2d2, Face, 0.); | |
627 | //:S4136 FindParameter(C2d1, C2d2, E, Face, preci); | |
628 | } | |
629 | else | |
630 | B.UpdateEdge(E, C2d1, Face, 0.); //preci | |
631 | } | |
632 | else { | |
633 | if(isSeam) { | |
634 | // When the edge is a Seam, it is better to find the topological | |
635 | // trimming right now. | |
636 | B.UpdateEdge(E, C2d2, C2d1, Face, 0.); | |
637 | //:S4136 FindParameter(C2d1, C2d2, E, Face, preci); | |
638 | } | |
639 | else | |
640 | B.UpdateEdge(E, C2d2, Face, 0.); | |
641 | } | |
642 | } | |
643 | else { | |
644 | TP->AddFail(StepEdge," Seam curve not mapped"); | |
645 | done = Standard_False; | |
646 | myError = StepToTopoDS_TranslateEdgeLoopOther; | |
647 | continue; | |
648 | } | |
649 | } | |
650 | else { | |
651 | ||
652 | // --------------------------- | |
653 | // The Edge is a "normal" edge | |
654 | // --------------------------- | |
655 | ||
656 | if (hasPcurve) { | |
657 | if ( !C2d.IsNull() && !isLikeSeam ) { | |
658 | B.UpdateEdge(E, C2d, Face, 0.); | |
659 | } | |
660 | else { | |
661 | TP->AddFail(StepEdge," Edge: Trimming of 2D curve failed"); | |
662 | // cout << "2D curve type : " << C2d->DynamicType() << endl; | |
663 | done = Standard_False; | |
664 | myError = StepToTopoDS_TranslateEdgeLoopOther; | |
665 | continue; | |
666 | } | |
667 | } | |
668 | } | |
669 | ||
670 | if (!E.IsNull()) { | |
671 | // B.Add(W,E); -- DABORD regarder degeneree manquante !!! | |
672 | } | |
673 | else { | |
674 | TP->AddFail(StepEdge," an Edge not mapped"); | |
675 | done = Standard_False; | |
676 | myError = StepToTopoDS_TranslateEdgeLoopOther; | |
677 | // continue; | |
678 | } | |
679 | } | |
680 | else { // The Edge is Not mapped => switch to next wire ? | |
681 | TP->AddFail(StepEdge," an Edge not mapped"); | |
682 | done = Standard_False; | |
683 | myError = StepToTopoDS_TranslateEdgeLoopOther; | |
684 | // continue; | |
685 | } | |
686 | ||
687 | if (done) B.Add (W,E); // on le fait ici. Sauf si erreur rencontree ... ! | |
688 | else { | |
689 | Handle(StepShape_Vertex) Vs1, Vs2; | |
690 | Vs1 = StepEdge->EdgeStart(); | |
691 | Vs2 = StepEdge->EdgeEnd(); | |
692 | if(!Vs1.IsNull() && !Vs2.IsNull() && Vs1==Vs2) { | |
693 | done = Standard_True; | |
694 | TP->AddFail(EL," Edge with equal vertices failed, scipped"); | |
695 | } | |
696 | } | |
697 | } | |
698 | ||
699 | // The EdgeLoop is binded in the Wire | |
700 | ||
701 | if (!done) { | |
702 | TP->AddFail(EL,"At least one edge failed : wire not done"); | |
703 | return; | |
704 | } | |
ab860031 | 705 | W.Closed (BRep_Tool::IsClosed (W)); |
7fd59977 | 706 | aTool.Bind(EL, W); |
707 | ||
708 | // ---------------------------------------------- | |
709 | // Computes the 2D parameter of Vertices on Edges | |
710 | // ---------------------------------------------- | |
711 | //pdn compute parameter of Vertices using progecting | |
712 | if (!aTool.ComputePCurve()) | |
713 | for (TopoDS_Iterator EdgeIt(W);EdgeIt.More();EdgeIt.Next()){ | |
714 | TopoDS_Edge edge = TopoDS::Edge(EdgeIt.Value()); | |
715 | Handle(ShapeFix_EdgeProjAux) myEdgePro = ShapeAlgo::AlgoContainer()->ToolContainer()->EdgeProjAux(); | |
716 | myEdgePro->Init (Face, edge); | |
717 | myEdgePro->Compute(preci); | |
718 | if (myEdgePro->IsFirstDone() && myEdgePro->IsLastDone()) { | |
e65d641a A |
719 | if (Abs (myEdgePro->FirstParam() - myEdgePro->LastParam()) < Precision::PConfusion()) |
720 | continue; | |
721 | B.Range(edge, Face,myEdgePro->FirstParam(), myEdgePro->LastParam()); | |
7fd59977 | 722 | } |
723 | else { | |
724 | RemoveSinglePCurve(edge, Face); | |
0797d9d3 | 725 | #ifdef OCCT_DEBUG |
7fd59977 | 726 | cout <<"Removing after prj"<<endl; |
727 | #endif | |
728 | } | |
729 | } | |
730 | ||
731 | myResult = W; | |
732 | myError = StepToTopoDS_TranslateEdgeLoopDone; | |
733 | done = Standard_True; | |
734 | // Check des PCurves SYSTEMATIQUE, s il n y en a que quelques unes | |
735 | // if (isPlane) RemovePCurves (W, Face); | |
736 | // else CheckPCurves (W, Face); | |
737 | CheckPCurves (W, Face,isPlane,preci); | |
738 | ||
739 | // -------------------------------------------- | |
740 | // Control the UVLoop (Closed and Head To Tail) | |
741 | // -------------------------------------------- | |
742 | ||
743 | // StepToTopoDS_GeometricToolError tError = | |
744 | // StepToTopoDS_GeometricTool::CloseUV(W, Face, aTool); | |
745 | // if(tError != StepToTopoDS_GeometricToolDone) { | |
746 | // TP->AddWarning(StepEdge,StepToTopoDS::DecodeGeometricToolError(tError)); | |
747 | // } | |
748 | return; | |
749 | } | |
750 | ||
751 | ||
752 | // ============================================================================ | |
753 | // Method : Value | |
754 | // Purpose : Return the mapped Shape | |
755 | // ============================================================================ | |
756 | ||
757 | const TopoDS_Shape& StepToTopoDS_TranslateEdgeLoop::Value() const | |
758 | { | |
759 | StdFail_NotDone_Raise_if(!done,""); | |
760 | return myResult; | |
761 | } | |
762 | ||
763 | // ============================================================================ | |
764 | // Method : Error | |
765 | // Purpose : Return the TranslateEdgeLoop error | |
766 | // ============================================================================ | |
767 | ||
768 | StepToTopoDS_TranslateEdgeLoopError StepToTopoDS_TranslateEdgeLoop::Error() const | |
769 | { | |
770 | return myError; | |
771 | } | |
772 |