1 // Created on: 1994-10-04
2 // Created by: Yves FRICAUD
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepBuilderAPI_MakeFace.hxx>
21 #include <BRepLib.hxx>
22 #include <BRepMAT2d_Explorer.hxx>
23 #include <BRepTools_WireExplorer.hxx>
24 #include <GCE2d_MakeArcOfCircle.hxx>
25 #include <GCE2d_MakeSegment.hxx>
26 #include <Geom2d_BezierCurve.hxx>
27 #include <Geom2d_BoundedCurve.hxx>
28 #include <Geom2d_BSplineCurve.hxx>
29 #include <Geom2d_Circle.hxx>
30 #include <Geom2d_Curve.hxx>
31 #include <Geom2d_Ellipse.hxx>
32 #include <Geom2d_Hyperbola.hxx>
33 #include <Geom2d_Line.hxx>
34 #include <Geom2d_OffsetCurve.hxx>
35 #include <Geom2d_Parabola.hxx>
36 #include <Geom2d_TrimmedCurve.hxx>
37 #include <Geom2dConvert.hxx>
38 #include <Geom_Curve.hxx>
39 #include <Geom_TrimmedCurve.hxx>
40 #include <GeomAbs_CurveType.hxx>
41 #include <GeomAPI.hxx>
44 #include <MAT2d_SequenceOfSequenceOfCurve.hxx>
45 #include <Precision.hxx>
46 #include <TColGeom2d_SequenceOfCurve.hxx>
49 #include <TopExp_Explorer.hxx>
50 #include <TopLoc_Location.hxx>
52 #include <TopoDS_Face.hxx>
53 #include <TopoDS_Shape.hxx>
54 #include <TopoDS_Wire.hxx>
55 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
58 // Modified by Sergey KHROMOV - Thu Dec 5 10:38:14 2002 Begin
59 static TopoDS_Edge MakeEdge(const Handle(Geom2d_Curve) &theCurve,
60 const TopoDS_Face &theFace,
61 const TopoDS_Vertex &theVFirst,
62 const TopoDS_Vertex &theVLast);
63 // Modified by Sergey KHROMOV - Thu Dec 5 10:38:16 2002 End
65 static GeomAbs_CurveType GetCurveType(const Handle(Geom2d_Curve)& theC2d);
66 static Handle(Geom2d_TrimmedCurve) AdjustCurveEnd (const Handle(Geom2d_BoundedCurve)& theC2d,
67 const gp_Pnt2d theP, const Standard_Boolean isFirst);
69 //=======================================================================
70 //function : BRepMAT2d_Explorer
72 //=======================================================================
74 BRepMAT2d_Explorer::BRepMAT2d_Explorer()
79 //=======================================================================
80 //function : BRepMAT2d_Explorer
82 //=======================================================================
84 BRepMAT2d_Explorer::BRepMAT2d_Explorer(const TopoDS_Face& aFace)
89 //=======================================================================
92 //=======================================================================
94 void BRepMAT2d_Explorer::Perform(const TopoDS_Face& aFace)
98 TopoDS_Face F = TopoDS::Face(aFace);
99 F.Orientation(TopAbs_FORWARD);
100 TopExp_Explorer Exp (F,TopAbs_WIRE);
101 // Modified by Sergey KHROMOV - Tue Nov 26 16:10:37 2002 Begin
102 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
103 TopoDS_Face aNewF = BRepBuilderAPI_MakeFace(aSurf, Precision::Confusion());
106 Add (TopoDS::Wire (Exp.Current()),F, aNewF);
110 BRepLib::BuildCurves3d(aNewF);
112 myModifShapes.Add(aFace, aNewF);
113 // CheckConnection();
114 // Modified by Sergey KHROMOV - Tue Nov 26 16:10:38 2002 End
117 //=======================================================================
120 //=======================================================================
122 void BRepMAT2d_Explorer::Add(const TopoDS_Wire& Spine,
123 const TopoDS_Face& aFace,
124 TopoDS_Face& aNewFace)
126 // Modified by Sergey KHROMOV - Tue Nov 26 14:25:46 2002 Begin
127 // This method is totally rewroted to include check
128 // of connection and creation of a new spine.
130 myIsClosed(currentContour) = (Spine.Closed()) ? Standard_True : Standard_False;
132 // Modified by skv - Wed Jun 23 12:23:01 2004 Integration Begin
133 // Taking into account side of bisecting loci construction.
134 // TopoDS_Wire aWFwd = TopoDS::Wire(Spine.Oriented(TopAbs_FORWARD));
135 // BRepTools_WireExplorer anExp(aWFwd, aFace);
136 BRepTools_WireExplorer anExp(Spine, aFace);
137 // Modified by skv - Wed Jun 23 12:23:02 2004 Integration End
138 TopTools_IndexedDataMapOfShapeShape anOldNewE;
143 TopoDS_Edge aFirstEdge = anExp.Current();
144 TopoDS_Edge aPrevEdge = aFirstEdge;
145 Standard_Real UFirst,ULast, aD;
146 Handle(Geom2d_Curve) C2d;
147 Handle(Geom2d_TrimmedCurve) CT2d;
148 Handle(Geom2d_TrimmedCurve) aFirstCurve;
152 // Modified by skv - Mon Jul 11 19:00:25 2005 Integration Begin
153 // Set the confusion tolerance in accordance with the further algo
154 // Standard_Real aTolConf = Precision::Confusion();
155 Standard_Real aTolConf = 1.e-8;
156 // Modified by skv - Mon Jul 11 19:00:25 2005 Integration End
157 Standard_Boolean isModif = Standard_False;
159 // Treatment of the first edge of a wire.
160 anOldNewE.Add(aFirstEdge, aFirstEdge);
161 C2d = BRep_Tool::CurveOnSurface (aFirstEdge, aFace, UFirst, ULast);
162 CT2d = new Geom2d_TrimmedCurve(C2d,UFirst,ULast);
164 if (aFirstEdge.Orientation() == TopAbs_REVERSED)
167 aPFirst = CT2d->Value(CT2d->FirstParameter());
168 aPLast = CT2d->Value(CT2d->LastParameter());
174 // Treatment of the next edges:
175 for (; anExp.More(); anExp.Next()) {
176 TopoDS_Edge anEdge = anExp.Current();
178 anOldNewE.Add(anEdge, anEdge);
179 C2d = BRep_Tool::CurveOnSurface (anEdge, aFace, UFirst, ULast);
180 CT2d = new Geom2d_TrimmedCurve(C2d,UFirst,ULast);
182 if (anEdge.Orientation() == TopAbs_REVERSED)
185 aPCurFirst = CT2d->Value(CT2d->FirstParameter());
187 aD=aPLast.Distance(aPCurFirst);
189 // There are two ways how to fill holes:
190 // First, to create a line between these two points.
191 // Second, create a BSpline curve and to add the last point of the previous
192 // curve as the first pole of the current one. Second method which
193 // is worse was performed before and leaved here. Otherwise too much
194 // code should be rewritten.
195 isModif = Standard_True;
197 Standard_Integer aNbC = theCurves.Value(currentContour).Length();
198 Handle(Geom2d_BoundedCurve) CPrev =
199 Handle(Geom2d_BoundedCurve)::DownCast(theCurves.ChangeValue(currentContour).ChangeValue(aNbC));
201 GeomAbs_CurveType TCPrev = GetCurveType(CPrev);
202 GeomAbs_CurveType TCCurr = GetCurveType(CT2d);
206 CT2d = AdjustCurveEnd (CT2d, aPLast, Standard_True);
207 // Creation of new edge.
208 TopoDS_Edge aNewEdge;
209 TopoDS_Vertex aVf = TopExp::FirstVertex(anEdge);
210 TopoDS_Vertex aVl = TopExp::LastVertex(anEdge);
212 if (anEdge.Orientation() == TopAbs_FORWARD)
213 aNewEdge = MakeEdge(CT2d, aNewFace, aVf, aVl);
215 aNewEdge = MakeEdge(CT2d->Reversed(), aNewFace, aVf, aVl);
217 aNewEdge.Orientation(anEdge.Orientation());
219 anOldNewE.ChangeFromKey(anEdge) = aNewEdge;
223 gp_Pnt2d aP = CT2d->Value(CT2d->FirstParameter());
224 CPrev = AdjustCurveEnd(CPrev, aP, Standard_False);
225 theCurves.ChangeValue(currentContour).ChangeValue(aNbC) = CPrev;
226 //Change previous edge
227 TopoDS_Edge aNewEdge;
228 TopoDS_Vertex aVf = TopExp::FirstVertex(aPrevEdge);
229 TopoDS_Vertex aVl = TopExp::LastVertex(aPrevEdge);
231 if (aPrevEdge.Orientation() == TopAbs_FORWARD)
232 aNewEdge = MakeEdge(CPrev, aNewFace, aVf, aVl);
234 aNewEdge = MakeEdge(CPrev->Reversed(), aNewFace, aVf, aVl);
236 aNewEdge.Orientation(aPrevEdge.Orientation());
238 anOldNewE.ChangeFromKey(aPrevEdge) = aNewEdge;
244 aPLast = CT2d->Value(CT2d->LastParameter());
249 // Check of the distance between the first and the last point of wire
250 // if the wire is closed.
251 if (myIsClosed(currentContour) && aPLast.Distance(aPFirst) > aTolConf) {
252 isModif = Standard_True;
255 Standard_Integer aNbC = theCurves.Value(currentContour).Length();
256 Handle(Geom2d_BoundedCurve) CPrev =
257 Handle(Geom2d_BoundedCurve)::DownCast(theCurves.ChangeValue(currentContour).ChangeValue(aNbC));
259 GeomAbs_CurveType TCPrev = GetCurveType(CPrev);
260 GeomAbs_CurveType TCCurr = GetCurveType(aFirstCurve);
264 aFirstCurve = AdjustCurveEnd(aFirstCurve, aPLast, Standard_True);
265 theCurves.ChangeValue(currentContour).ChangeValue(1) = aFirstCurve;
266 // Creation of new edge.
267 TopoDS_Edge aNewEdge;
268 TopoDS_Vertex aVf = TopExp::FirstVertex(aFirstEdge);
269 TopoDS_Vertex aVl = TopExp::LastVertex(aFirstEdge);
271 if (aFirstEdge.Orientation() == TopAbs_FORWARD)
272 aNewEdge = MakeEdge(aFirstCurve, aNewFace, aVf, aVl);
274 aNewEdge = MakeEdge(aFirstCurve->Reversed(), aNewFace, aVf, aVl);
276 aNewEdge.Orientation(aFirstEdge.Orientation());
278 anOldNewE.ChangeFromKey(aFirstEdge) = aNewEdge;
282 gp_Pnt2d aP = aFirstCurve->Value(aFirstCurve->FirstParameter());
283 CPrev = AdjustCurveEnd(CPrev, aP, Standard_False);
284 theCurves.ChangeValue(currentContour).ChangeValue(aNbC) = CPrev;
285 //Change previous edge
286 TopoDS_Edge aNewEdge;
287 TopoDS_Vertex aVf = TopExp::FirstVertex(aPrevEdge);
288 TopoDS_Vertex aVl = TopExp::LastVertex(aPrevEdge);
290 if (aPrevEdge.Orientation() == TopAbs_FORWARD)
291 aNewEdge = MakeEdge(CPrev, aNewFace, aVf, aVl);
293 aNewEdge = MakeEdge(CPrev->Reversed(), aNewFace, aVf, aVl);
295 aNewEdge.Orientation(aPrevEdge.Orientation());
297 anOldNewE.ChangeFromKey(aPrevEdge) = aNewEdge;
303 TopoDS_Wire aNewWire;
304 BRep_Builder aBuilder;
308 Standard_Integer aNbEdges = anOldNewE.Extent();
310 aBuilder.MakeWire(aNewWire);
312 for (i = 1; i <= aNbEdges; i++) {
313 const TopoDS_Shape &aKey = anOldNewE.FindKey(i);
314 const TopoDS_Shape &aNewEdge = anOldNewE.FindFromIndex(i);
316 aBuilder.Add(aNewWire, aNewEdge);
317 myModifShapes.Add(aKey, aNewEdge);
320 if (myIsClosed(currentContour))
321 aNewWire.Closed(Standard_True);
323 // Modified by skv - Fri Nov 12 17:22:12 2004 Integration Begin
324 // The orientation of wire is already taken into account.
325 // aNewWire.Orientation(Spine.Orientation());
326 // Modified by skv - Fri Nov 12 17:22:12 2004 Integration End
327 myModifShapes.Add(Spine, aNewWire);
331 aBuilder.Add(aNewFace, aNewWire);
332 // Modified by Sergey KHROMOV - Tue Nov 26 14:25:53 2002 End
335 //=======================================================================
336 //function : CheckConnection
338 //=======================================================================
340 // Modified by Sergey KHROMOV - Tue Nov 26 17:21:44 2002 Begin
341 // void BRepMAT2d_Explorer::CheckConnection()
343 // for (Standard_Integer i = 1; i <= theCurves.Length(); i++)
344 // for (Standard_Integer j = 2; j <= theCurves(i).Length(); j++)
346 // gp_Pnt2d P1 = theCurves(i)(j-1)->Value( theCurves(i)(j-1)->LastParameter() );
347 // gp_Pnt2d P2 = theCurves(i)(j)->Value( theCurves(i)(j)->FirstParameter() );
348 // if (P1.Distance( P2 ) > Precision::Confusion())
350 // Handle( Geom2d_BSplineCurve ) BCurve;
351 // if (theCurves(i)(j)->DynamicType() != STANDARD_TYPE(Geom2d_BSplineCurve))
352 // BCurve = Geom2dConvert::CurveToBSplineCurve( theCurves(i)(j) );
354 // BCurve = Handle( Geom2d_BSplineCurve )::DownCast( theCurves(i)(j) );
355 // BCurve->SetPole( 1, P1 );
356 // theCurves(i)(j) = new Geom2d_TrimmedCurve( BCurve, BCurve->FirstParameter(), BCurve->LastParameter() );
360 // Modified by Sergey KHROMOV - Tue Nov 26 17:21:29 2002 End
362 //=======================================================================
365 //=======================================================================
367 void BRepMAT2d_Explorer::Clear()
371 // Modified by Sergey KHROMOV - Wed Mar 6 16:07:55 2002 Begin
373 myModifShapes.Clear();
374 // Modified by Sergey KHROMOV - Wed Mar 6 16:07:55 2002 End
378 //=======================================================================
379 //function : NewContour
381 //=======================================================================
383 void BRepMAT2d_Explorer::NewContour()
385 TColGeom2d_SequenceOfCurve Contour;
386 theCurves.Append(Contour);
387 // Modified by Sergey KHROMOV - Wed Mar 6 16:12:05 2002 Begin
388 myIsClosed.Append(Standard_False);
389 // Modified by Sergey KHROMOV - Wed Mar 6 16:12:05 2002 End
394 //=======================================================================
397 //=======================================================================
399 void BRepMAT2d_Explorer::Add(const Handle(Geom2d_Curve)& aCurve)
401 theCurves.ChangeValue(currentContour).Append(aCurve);
404 //=======================================================================
405 //function : NumberOfContours
407 //=======================================================================
409 Standard_Integer BRepMAT2d_Explorer::NumberOfContours() const
411 return theCurves.Length() ;
415 //=======================================================================
416 //function : NumberOfCurves
418 //=======================================================================
420 Standard_Integer BRepMAT2d_Explorer::NumberOfCurves
421 (const Standard_Integer IndexContour)
424 return theCurves.Value(IndexContour).Length();
428 //=======================================================================
431 //=======================================================================
433 void BRepMAT2d_Explorer::Init(const Standard_Integer IndexContour)
435 currentContour = IndexContour;
440 //=======================================================================
443 //=======================================================================
445 Standard_Boolean BRepMAT2d_Explorer::More() const
447 return (current <= NumberOfCurves(currentContour));
451 //=======================================================================
454 //=======================================================================
456 void BRepMAT2d_Explorer::Next()
462 //=======================================================================
465 //=======================================================================
467 Handle(Geom2d_Curve) BRepMAT2d_Explorer::Value() const
469 return theCurves.Value(currentContour).Value(current);
472 //=======================================================================
475 //=======================================================================
477 TopoDS_Shape BRepMAT2d_Explorer::Shape() const
483 //=======================================================================
486 //=======================================================================
488 const TColGeom2d_SequenceOfCurve& BRepMAT2d_Explorer::Contour
489 (const Standard_Integer IC)
492 return theCurves.Value(IC);
496 // Modified by Sergey KHROMOV - Wed Mar 6 17:40:07 2002 Begin
497 //=======================================================================
498 //function : IsModified
500 //=======================================================================
502 Standard_Boolean BRepMAT2d_Explorer::IsModified
503 (const TopoDS_Shape &aShape) const
505 if (myModifShapes.Contains(aShape)) {
506 const TopoDS_Shape &aNewShape = myModifShapes.FindFromKey(aShape);
507 const Standard_Boolean isSame = aNewShape.IsSame(aShape);
512 return Standard_False;
515 //=======================================================================
516 //function : ModifiedShape
518 //=======================================================================
520 TopoDS_Shape BRepMAT2d_Explorer::ModifiedShape
521 (const TopoDS_Shape &aShape) const
523 if (myModifShapes.Contains(aShape)) {
524 const TopoDS_Shape &aNewShape = myModifShapes.FindFromKey(aShape);
532 //=======================================================================
533 //function : GetIsClosed
535 //=======================================================================
537 const TColStd_SequenceOfBoolean &BRepMAT2d_Explorer::GetIsClosed() const
542 //=======================================================================
543 //function : MakeEdge
544 //purpose : Creation of an edge by 2d curve, face and two vertices.
545 //=======================================================================
547 TopoDS_Edge MakeEdge(const Handle(Geom2d_Curve) &theCurve,
548 const TopoDS_Face &theFace,
549 const TopoDS_Vertex &theVFirst,
550 const TopoDS_Vertex &theVLast)
552 TopoDS_Edge aNewEdge;
553 BRep_Builder aBuilder;
554 Standard_Real aTol = Precision::Confusion();
555 Standard_Real aFPar = theCurve->FirstParameter();
556 Standard_Real aLPar = theCurve->LastParameter();
558 aBuilder.MakeEdge(aNewEdge);
559 aBuilder.UpdateEdge(aNewEdge, theCurve, theFace, aTol);
560 aBuilder.Add(aNewEdge, theVFirst.Oriented(TopAbs_FORWARD));
561 aBuilder.Add(aNewEdge, theVLast.Oriented(TopAbs_REVERSED));
562 aBuilder.Range(aNewEdge, aFPar, aLPar);
566 // Modified by Sergey KHROMOV - Wed Mar 6 17:40:14 2002 End
568 //=======================================================================
569 //function : GetCurveType
570 //purpose : Get curve type.
571 //=======================================================================
573 GeomAbs_CurveType GetCurveType(const Handle(Geom2d_Curve)& theC2d)
575 GeomAbs_CurveType aTypeCurve = GeomAbs_OtherCurve;
576 Handle(Standard_Type) TheType = theC2d->DynamicType();
577 if ( TheType == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
578 TheType = Handle(Geom2d_TrimmedCurve)::DownCast (theC2d)->BasisCurve()->DynamicType();
581 if ( TheType == STANDARD_TYPE(Geom2d_Circle)) {
582 aTypeCurve = GeomAbs_Circle;
584 else if ( TheType ==STANDARD_TYPE(Geom2d_Line)) {
585 aTypeCurve = GeomAbs_Line;
587 else if ( TheType == STANDARD_TYPE(Geom2d_Ellipse)) {
588 aTypeCurve = GeomAbs_Ellipse;
590 else if ( TheType == STANDARD_TYPE(Geom2d_Parabola)) {
591 aTypeCurve = GeomAbs_Parabola;
593 else if ( TheType == STANDARD_TYPE(Geom2d_Hyperbola)) {
594 aTypeCurve = GeomAbs_Hyperbola;
596 else if ( TheType == STANDARD_TYPE(Geom2d_BezierCurve)) {
597 aTypeCurve = GeomAbs_BezierCurve;
599 else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
600 aTypeCurve = GeomAbs_BSplineCurve;
602 else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve)) {
603 aTypeCurve = GeomAbs_OffsetCurve;
606 aTypeCurve = GeomAbs_OtherCurve;
610 //=======================================================================
611 //function : AdjustCurveEnd
613 //=======================================================================
614 Handle(Geom2d_TrimmedCurve) AdjustCurveEnd (const Handle(Geom2d_BoundedCurve)& theC2d,
615 const gp_Pnt2d theP, const Standard_Boolean isFirst)
617 GeomAbs_CurveType aType = GetCurveType(theC2d);
618 if(aType == GeomAbs_Line)
623 gp_Pnt2d aP = theC2d->Value(theC2d->LastParameter());
624 return GCE2d_MakeSegment(theP, aP);
628 gp_Pnt2d aP = theC2d->Value(theC2d->FirstParameter());
629 return GCE2d_MakeSegment(aP, theP);
634 //Convert to BSpline and adjust first pole
635 Handle(Geom2d_BSplineCurve) BCurve =
636 Geom2dConvert::CurveToBSplineCurve(theC2d, Convert_QuasiAngular);
639 BCurve->SetPole(1, theP);
640 return new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(),
641 BCurve->LastParameter());
645 BCurve->SetPole(BCurve->NbPoles(), theP);
646 return new Geom2d_TrimmedCurve(BCurve, BCurve->FirstParameter(),
647 BCurve->LastParameter());