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