X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_ShapeDriver.cxx;h=54d149b3a625b3fca8706082fe915d45f14c576c;hb=3059f9d5521dd7c91c35c50afbd6beb18b8826fd;hp=df96b659d131557ef2c6364c92c3bef55ac2a441;hpb=f4e80938ef58dcba151bba62136950bff95ec85f;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index df96b659d..54d149b3a 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -1,36 +1,84 @@ - -using namespace std; -#include "GEOMImpl_ShapeDriver.hxx" -#include "GEOMImpl_IShapes.hxx" -#include "GEOMImpl_IShapesOperations.hxx" -#include "GEOMImpl_Types.hxx" -#include "GEOM_Function.hxx" +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include + +#include +#include +#include + +#include + +// OCCT Includes +#include +#include +#include #include #include #include #include #include -#include #include #include #include #include #include -#include +#include +#include +#include +#include +#include + +#include +#include #include #include #include #include #include +#include #include #include #include +#include #include + #include -#include -#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include #include #include @@ -73,106 +121,214 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const if (aType == WIRE_EDGES) { Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); - unsigned int ind, nbshapes = aShapes->Length(); + TopoDS_Wire aWire; + B.MakeWire(aWire); // add edges - BRepBuilderAPI_MakeWire MW; - for (ind = 1; ind <= nbshapes; ind++) { + for (unsigned int ind = 1; ind <= aShapes->Length(); ind++) { Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); TopoDS_Shape aShape_i = aRefShape->GetValue(); if (aShape_i.IsNull()) { Standard_NullObject::Raise("Shape for wire construction is null"); } - if (aShape_i.ShapeType() == TopAbs_EDGE) - MW.Add(TopoDS::Edge(aShape_i)); - else if (aShape_i.ShapeType() == TopAbs_WIRE) - MW.Add(TopoDS::Wire(aShape_i)); - else - Standard_TypeMismatch::Raise - ("Shape for wire construction is neither an edge nor a wire"); + if (aShape_i.ShapeType() == TopAbs_EDGE || aShape_i.ShapeType() == TopAbs_WIRE) { + TopExp_Explorer exp (aShape_i, TopAbs_EDGE); + for (; exp.More(); exp.Next()) + B.Add(aWire, TopoDS::Edge(exp.Current())); + } else { + Standard_TypeMismatch::Raise + ("Shape for wire construction is neither an edge nor a wire"); + } } - if (!MW.IsDone()) { + // fix edges order + Handle(ShapeFix_Wire) aFW = new ShapeFix_Wire; + aFW->Load(aWire); + aFW->FixReorder(); + + if (aFW->StatusReorder(ShapeExtend_FAIL1)) { + Standard_ConstructionError::Raise("Wire construction failed: several loops detected"); + } else if (aFW->StatusReorder(ShapeExtend_FAIL)) { Standard_ConstructionError::Raise("Wire construction failed"); + } else { } - aShape = MW; - } else if (aType == FACE_WIRE) { + // IMP 0019766: Building a Wire from unconnected edges by introducing a tolerance + Standard_Real aTolerance = aCI.GetTolerance(); + if (aTolerance < Precision::Confusion()) + aTolerance = Precision::Confusion(); + + aFW->ClosedWireMode() = Standard_False; + aFW->FixConnected(aTolerance); + if (aFW->StatusConnected(ShapeExtend_FAIL)) { + Standard_ConstructionError::Raise("Wire construction failed: cannot build connected wire"); + } + // IMP 0019766 + if (aFW->StatusConnected(ShapeExtend_DONE3)) { + // Confused with but not Analyzer.Precision(), set the same + aFW->FixGapsByRangesMode() = Standard_True; + if (aFW->FixGaps3d()) { + Handle(ShapeExtend_WireData) sbwd = aFW->WireData(); + Handle(ShapeFix_Edge) aFe = new ShapeFix_Edge; + for (Standard_Integer iedge = 1; iedge <= sbwd->NbEdges(); iedge++) { + TopoDS_Edge aEdge = TopoDS::Edge(sbwd->Edge(iedge)); + aFe->FixVertexTolerance(aEdge); + aFe->FixSameParameter(aEdge); + } + } + else if (aFW->StatusGaps3d(ShapeExtend_FAIL)) { + Standard_ConstructionError::Raise("Wire construction failed: cannot fix 3d gaps"); + } + } + aShape = aFW->WireAPIMake(); + } + else if (aType == FACE_WIRE) { Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aShapeBase = aRefBase->GetValue(); - if (aShapeBase.IsNull() || aShapeBase.ShapeType() != TopAbs_WIRE) { + if (aShapeBase.IsNull()) Standard_NullObject::Raise("Argument Shape is null"); + TopoDS_Wire W; + if (aShapeBase.ShapeType() == TopAbs_WIRE) { + W = TopoDS::Wire(aShapeBase); + // check the wire is closed + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(W, aV1, aV2); + if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) ) + aShapeBase.Closed(true); + else + Standard_NullObject::Raise + ("Shape for face construction is not closed"); + } + else if (aShapeBase.ShapeType() == TopAbs_EDGE && aShapeBase.Closed()) { + BRepBuilderAPI_MakeWire MW; + MW.Add(TopoDS::Edge(aShapeBase)); + if (!MW.IsDone()) { + Standard_ConstructionError::Raise("Wire construction failed"); + } + W = MW; + } + else { Standard_NullObject::Raise - ("Shape for face construction is null or not a wire"); + ("Shape for face construction is neither a wire nor a closed edge"); } - TopoDS_Wire W = TopoDS::Wire(aShapeBase); - BRepBuilderAPI_MakeFace MF (W, aCI.GetIsPlanar()); - if (!MF.IsDone()) { + GEOMImpl_Block6Explorer::MakeFace(W, aCI.GetIsPlanar(), aShape); + if (aShape.IsNull()) { Standard_ConstructionError::Raise("Face construction failed"); } - aShape = MF.Shape(); + } + else if (aType == FACE_WIRES) { + // Try to build a face from a set of wires and edges + int ind; - } else if (aType == FACE_WIRES) { Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); + int nbshapes = aShapes->Length(); + if (nbshapes < 1) { + Standard_ConstructionError::Raise("No wires or edges given"); + } - // first wire - Handle(GEOM_Function) aRefWire = Handle(GEOM_Function)::DownCast(aShapes->Value(1)); - TopoDS_Shape aWire = aRefWire->GetValue(); - if (aWire.IsNull() || aWire.ShapeType() != TopAbs_WIRE) { - Standard_NullObject::Raise("Shape for face construction is null or not a wire"); + // 1. Extract all edges from the given arguments + TopTools_MapOfShape aMapEdges; + Handle(TopTools_HSequenceOfShape) aSeqEdgesIn = new TopTools_HSequenceOfShape; + + for (ind = 1; ind <= nbshapes; ind++) { + Handle(GEOM_Function) aRefSh_i = Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); + TopoDS_Shape aSh_i = aRefSh_i->GetValue(); + + TopExp_Explorer anExpE_i (aSh_i, TopAbs_EDGE); + for (; anExpE_i.More(); anExpE_i.Next()) { + if (aMapEdges.Add(anExpE_i.Current())) { + aSeqEdgesIn->Append(anExpE_i.Current()); + } + } + } + + // 2. Connect edges to wires of maximum length + Handle(TopTools_HSequenceOfShape) aSeqWiresOut; + ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdgesIn, Precision::Confusion(), + /*shared*/Standard_False, aSeqWiresOut); + + // 3. Separate closed wires + Handle(TopTools_HSequenceOfShape) aSeqClosedWires = new TopTools_HSequenceOfShape; + Handle(TopTools_HSequenceOfShape) aSeqOpenWires = new TopTools_HSequenceOfShape; + for (ind = 1; ind <= aSeqWiresOut->Length(); ind++) { + if (aSeqWiresOut->Value(ind).Closed()) + aSeqClosedWires->Append(aSeqWiresOut->Value(ind)); + else + aSeqOpenWires->Append(aSeqWiresOut->Value(ind)); } - TopoDS_Wire W = TopoDS::Wire(aWire); - // basic face - BRepBuilderAPI_MakeFace MF (W, aCI.GetIsPlanar()); - if (!MF.IsDone()) { + if (aSeqClosedWires->Length() < 1) { + Standard_ConstructionError::Raise + ("There is no closed contour can be built from the given arguments"); + } + + // 4. Build a face / list of faces from all the obtained closed wires + + // 4.a. Basic face + TopoDS_Shape aFFace; + TopoDS_Wire aW1 = TopoDS::Wire(aSeqClosedWires->Value(1)); + GEOMImpl_Block6Explorer::MakeFace(aW1, aCI.GetIsPlanar(), aFFace); + if (aFFace.IsNull()) { Standard_ConstructionError::Raise("Face construction failed"); } - TopoDS_Shape FFace = MF.Shape(); - if (!FFace.IsNull()) { - unsigned int ind, nbshapes = aShapes->Length(); - if (nbshapes == 1) { - aShape = FFace; - - } else if (nbshapes >= 2) { - TopoDS_Compound C; - BRep_Builder aBuilder; - aBuilder.MakeCompound(C); - BRepAlgo_FaceRestrictor FR; - - TopAbs_Orientation OriF = FFace.Orientation(); - TopoDS_Shape aLocalS = FFace.Oriented(TopAbs_FORWARD); - FR.Init(TopoDS::Face(aLocalS), Standard_False, Standard_True); - - for (ind = 1; ind <= nbshapes; ind++) { - Handle(GEOM_Function) aRefWire_i = - Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); - TopoDS_Shape aWire_i = aRefWire_i->GetValue(); - if (aWire_i.IsNull() || aWire_i.ShapeType() != TopAbs_WIRE) { - Standard_NullObject::Raise("Shape for face construction is null or not a wire"); - } - - FR.Add(TopoDS::Wire(aWire_i)); - } - FR.Perform(); + // 4.b. Add other wires + if (aSeqClosedWires->Length() == 1) { + aShape = aFFace; + } + else { + TopoDS_Compound C; + BRep_Builder aBuilder; + aBuilder.MakeCompound(C); + BRepAlgo_FaceRestrictor FR; + + TopAbs_Orientation OriF = aFFace.Orientation(); + TopoDS_Shape aLocalS = aFFace.Oriented(TopAbs_FORWARD); + FR.Init(TopoDS::Face(aLocalS), Standard_False, Standard_True); + + for (ind = 1; ind <= aSeqClosedWires->Length(); ind++) { + TopoDS_Wire aW = TopoDS::Wire(aSeqClosedWires->Value(ind)); + FR.Add(aW); + } - if (FR.IsDone()) { - int k = 0; - TopoDS_Shape aFace; - for (; FR.More(); FR.Next()) { - aFace = FR.Current().Oriented(OriF); - aBuilder.Add(C, aFace); - k++; - } - if (k == 1) { - aShape = aFace; - } else { - aShape = C; - } - } + FR.Perform(); + + if (FR.IsDone()) { + int k = 0; + TopoDS_Shape aFace; + for (; FR.More(); FR.Next()) { + aFace = FR.Current().Oriented(OriF); + aBuilder.Add(C, aFace); + k++; + } + if (k == 1) { + aShape = aFace; + } else { + aShape = C; + } } } - } else if (aType == SHELL_FACES) { + + // 5. Add all open wires to the result + if (aSeqOpenWires->Length() > 0) { + //Standard_ConstructionError::Raise("There are some open wires"); + TopoDS_Compound C; + BRep_Builder aBuilder; + if (aSeqClosedWires->Length() == 1) { + aBuilder.MakeCompound(C); + aBuilder.Add(C, aShape); + } + else { + C = TopoDS::Compound(aShape); + } + + for (ind = 1; ind <= aSeqOpenWires->Length(); ind++) { + aBuilder.Add(C, aSeqOpenWires->Value(ind)); + } + + aShape = C; + } + } + else if (aType == SHELL_FACES) { Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -189,17 +345,29 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aSewing.Perform(); - TopExp_Explorer exp (aSewing.SewedShape(), TopAbs_SHELL); - Standard_Integer ish = 0; - for (; exp.More(); exp.Next()) { - aShape = exp.Current(); - ish++; + TopoDS_Shape sh = aSewing.SewedShape(); + if( sh.ShapeType()==TopAbs_FACE && nbshapes==1 ) { + // case for creation of shell from one face - PAL12722 (skl 26.06.2006) + TopoDS_Shell ss; + B.MakeShell(ss); + B.Add(ss,sh); + aShape = ss; } + else { + //TopExp_Explorer exp (aSewing.SewedShape(), TopAbs_SHELL); + TopExp_Explorer exp (sh, TopAbs_SHELL); + Standard_Integer ish = 0; + for (; exp.More(); exp.Next()) { + aShape = exp.Current(); + ish++; + } - if (ish != 1) - aShape = aSewing.SewedShape(); + if (ish != 1) + aShape = aSewing.SewedShape(); + } - } else if (aType == SOLID_SHELL) { + } + else if (aType == SOLID_SHELL) { Handle(GEOM_Function) aRefShell = aCI.GetBase(); TopoDS_Shape aShapeShell = aRefShell->GetValue(); if (aShapeShell.IsNull() || aShapeShell.ShapeType() != TopAbs_SHELL) { @@ -221,7 +389,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = Sol; - } else if (aType == SOLID_SHELLS) { + } + else if (aType == SOLID_SHELLS) { Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); Standard_Integer ish = 0; @@ -243,16 +412,12 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const if ( ish == 0 ) return 0; BRepClass3d_SolidClassifier SC (Sol); SC.PerformInfinitePoint(Precision::Confusion()); - switch (SC.State()) { - case TopAbs_IN: - aShape = Sol.Reversed(); break; - case TopAbs_OUT: - aShape = Sol; break; - default: // not closed shell? - return 0; - } - - } else if (aType == COMPOUND_SHAPES) { + if (SC.State() == TopAbs_IN) + aShape = Sol.Reversed(); + else + aShape = Sol; + } + else if (aType == COMPOUND_SHAPES) { Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -270,27 +435,364 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = C; - } else if (aType == REVERSE_ORIENTATION) { + } + else if (aType == REVERSE_ORIENTATION) { Handle(GEOM_Function) aRefShape = aCI.GetBase(); TopoDS_Shape aShape_i = aRefShape->GetValue(); if (aShape_i.IsNull()) { Standard_NullObject::Raise("Shape for reverse is null"); } - + BRepBuilderAPI_Copy Copy(aShape_i); if( Copy.IsDone() ) { TopoDS_Shape tds = Copy.Shape(); if( tds.IsNull() ) { - Standard_ConstructionError::Raise("Orientation aborted : Can not reverse the shape"); + Standard_ConstructionError::Raise("Orientation aborted : Can not reverse the shape"); } if( tds.Orientation() == TopAbs_FORWARD) - tds.Orientation(TopAbs_REVERSED) ; + tds.Orientation(TopAbs_REVERSED); else - tds.Orientation(TopAbs_FORWARD) ; + tds.Orientation(TopAbs_FORWARD); aShape = tds; - } + } + } + else if (aType == EDGE_WIRE) { + Handle(GEOM_Function) aRefBase = aCI.GetBase(); + TopoDS_Shape aWire = aRefBase->GetValue(); + Standard_Real LinTol = aCI.GetTolerance(); + Standard_Real AngTol = aCI.GetAngularTolerance(); + if (aWire.IsNull()) Standard_NullObject::Raise("Argument Wire is null"); + + TopoDS_Edge ResEdge; + + BRepLib::BuildCurves3d(aWire); + Handle(ShapeFix_Shape) Fixer = new ShapeFix_Shape(aWire); + Fixer->SetPrecision(LinTol); + Fixer->SetMaxTolerance(LinTol); + Fixer->Perform(); + TopoDS_Wire theWire = TopoDS::Wire(Fixer->Shape()); + + TColGeom_SequenceOfCurve CurveSeq; + TopTools_SequenceOfShape LocSeq; + TColStd_SequenceOfReal FparSeq; + TColStd_SequenceOfReal LparSeq; + TColStd_SequenceOfReal TolSeq; + GeomAbs_CurveType CurType; + TopoDS_Vertex FirstVertex, LastVertex; + + BRepTools_WireExplorer wexp(theWire) ; + for (; wexp.More(); wexp.Next()) + { + TopoDS_Edge anEdge = wexp.Current(); + Standard_Real fpar, lpar; + TopLoc_Location aLoc; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aLoc, fpar, lpar); + if (aCurve.IsNull()) + continue; + + BRepAdaptor_Curve BAcurve(anEdge); + GeomAbs_CurveType aType = BAcurve.GetType(); + + Handle(Geom_Curve) aBasisCurve = BAcurve.Curve().Curve(); + + if (aBasisCurve->IsPeriodic()) + ElCLib::AdjustPeriodic(aBasisCurve->FirstParameter(), aBasisCurve->LastParameter(), + Precision::PConfusion(), fpar, lpar); + + if (CurveSeq.IsEmpty()) + { + CurveSeq.Append(aCurve); + TopoDS_Shape aLocShape; + aLocShape.Location(aLoc); + aLocShape.Orientation(wexp.Orientation()); + LocSeq.Append(aLocShape); + FparSeq.Append(fpar); + LparSeq.Append(lpar); + CurType = aType; + FirstVertex = wexp.CurrentVertex(); + } + else + { + Standard_Boolean Done = Standard_False; + Standard_Real NewFpar, NewLpar; + GeomAdaptor_Curve GAprevcurve(CurveSeq.Last()); + TopoDS_Vertex CurVertex = wexp.CurrentVertex(); + TopoDS_Vertex CurFirstVer = TopExp::FirstVertex(anEdge); + TopAbs_Orientation ConnectByOrigin = (CurVertex.IsSame(CurFirstVer))? TopAbs_FORWARD : TopAbs_REVERSED; + if (aCurve == CurveSeq.Last()) + { + NewFpar = fpar; + NewLpar = lpar; + if (aBasisCurve->IsPeriodic()) + { + if (NewLpar < NewFpar) + NewLpar += aBasisCurve->Period(); + if (ConnectByOrigin == TopAbs_FORWARD) + ElCLib::AdjustPeriodic(FparSeq.Last(), + FparSeq.Last() + aBasisCurve->Period(), + Precision::PConfusion(), NewFpar, NewLpar); + else + ElCLib::AdjustPeriodic(FparSeq.Last() - aBasisCurve->Period(), + FparSeq.Last(), + Precision::PConfusion(), NewFpar, NewLpar); + } + Done = Standard_True; + } + else if (aType == CurType && + aType != GeomAbs_BezierCurve && + aType != GeomAbs_BSplineCurve && + aType != GeomAbs_OtherCurve) + { + switch (aType) + { + case GeomAbs_Line: + { + gp_Lin aLine = BAcurve.Line(); + gp_Lin PrevLine = GAprevcurve.Line(); + if (aLine.Contains(PrevLine.Location(), LinTol) && + aLine.Direction().IsParallel(PrevLine.Direction(), AngTol)) + { + gp_Pnt P1 = ElCLib::Value(fpar, aLine); + gp_Pnt P2 = ElCLib::Value(lpar, aLine); + NewFpar = ElCLib::Parameter(PrevLine, P1); + NewLpar = ElCLib::Parameter(PrevLine, P2); + if (NewLpar < NewFpar) + { + Standard_Real MemNewFpar = NewFpar; + NewFpar = NewLpar; + NewLpar = MemNewFpar; + ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin); + } + Done = Standard_True; + } + break; + } + case GeomAbs_Circle: + { + gp_Circ aCircle = BAcurve.Circle(); + gp_Circ PrevCircle = GAprevcurve.Circle(); + if (aCircle.Location().Distance(PrevCircle.Location()) <= LinTol && + Abs(aCircle.Radius() - PrevCircle.Radius()) <= LinTol && + aCircle.Axis().IsParallel(PrevCircle.Axis(), AngTol)) + { + if (aCircle.Axis().Direction() * PrevCircle.Axis().Direction() < 0.) + { + Standard_Real memfpar = fpar; + fpar = lpar; + lpar = memfpar; + ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin); + } + gp_Pnt P1 = ElCLib::Value(fpar, aCircle); + gp_Pnt P2 = ElCLib::Value(lpar, aCircle); + NewFpar = ElCLib::Parameter(PrevCircle, P1); + NewLpar = ElCLib::Parameter(PrevCircle, P2); + if (NewLpar < NewFpar) + NewLpar += 2.*PI; + //Standard_Real MemNewFpar = NewFpar, MemNewLpar = NewLpar; + if (ConnectByOrigin == TopAbs_FORWARD) + ElCLib::AdjustPeriodic(FparSeq.Last(), + FparSeq.Last() + 2.*PI, + Precision::PConfusion(), NewFpar, NewLpar); + else + ElCLib::AdjustPeriodic(FparSeq.Last() - 2.*PI, + FparSeq.Last(), + Precision::PConfusion(), NewFpar, NewLpar); + Done = Standard_True; + } + break; + } + case GeomAbs_Ellipse: + { + gp_Elips anEllipse = BAcurve.Ellipse(); + gp_Elips PrevEllipse = GAprevcurve.Ellipse(); + if (anEllipse.Focus1().Distance(PrevEllipse.Focus1()) <= LinTol && + anEllipse.Focus2().Distance(PrevEllipse.Focus2()) <= LinTol && + Abs(anEllipse.MajorRadius() - PrevEllipse.MajorRadius()) <= LinTol && + Abs(anEllipse.MinorRadius() - PrevEllipse.MinorRadius()) <= LinTol && + anEllipse.Axis().IsParallel(PrevEllipse.Axis(), AngTol)) + { + if (anEllipse.Axis().Direction() * PrevEllipse.Axis().Direction() < 0.) + { + Standard_Real memfpar = fpar; + fpar = lpar; + lpar = memfpar; + ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin); + } + gp_Pnt P1 = ElCLib::Value(fpar, anEllipse); + gp_Pnt P2 = ElCLib::Value(lpar, anEllipse); + NewFpar = ElCLib::Parameter(PrevEllipse, P1); + NewLpar = ElCLib::Parameter(PrevEllipse, P2); + if (NewLpar < NewFpar) + NewLpar += 2.*PI; + if (ConnectByOrigin == TopAbs_FORWARD) + ElCLib::AdjustPeriodic(FparSeq.Last(), + FparSeq.Last() + 2.*PI, + Precision::PConfusion(), NewFpar, NewLpar); + else + ElCLib::AdjustPeriodic(FparSeq.Last() - 2.*PI, + FparSeq.Last(), + Precision::PConfusion(), NewFpar, NewLpar); + Done = Standard_True; + } + break; + } + case GeomAbs_Hyperbola: + { + gp_Hypr aHypr = BAcurve.Hyperbola(); + gp_Hypr PrevHypr = GAprevcurve.Hyperbola(); + if (aHypr.Focus1().Distance(PrevHypr.Focus1()) <= LinTol && + aHypr.Focus2().Distance(PrevHypr.Focus2()) <= LinTol && + Abs(aHypr.MajorRadius() - PrevHypr.MajorRadius()) <= LinTol && + Abs(aHypr.MinorRadius() - PrevHypr.MinorRadius()) <= LinTol && + aHypr.Axis().IsParallel(PrevHypr.Axis(), AngTol)) + { + gp_Pnt P1 = ElCLib::Value(fpar, aHypr); + gp_Pnt P2 = ElCLib::Value(lpar, aHypr); + NewFpar = ElCLib::Parameter(PrevHypr, P1); + NewLpar = ElCLib::Parameter(PrevHypr, P2); + if (NewLpar < NewFpar) + { + Standard_Real MemNewFpar = NewFpar; + NewFpar = NewLpar; + NewLpar = MemNewFpar; + ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin); + } + Done = Standard_True; + } + break; + } + case GeomAbs_Parabola: + { + gp_Parab aParab = BAcurve.Parabola(); + gp_Parab PrevParab = GAprevcurve.Parabola(); + if (aParab.Location().Distance(PrevParab.Location()) <= LinTol && + aParab.Focus().Distance(PrevParab.Focus()) <= LinTol && + Abs(aParab.Focal() - PrevParab.Focal()) <= LinTol && + aParab.Axis().IsParallel(PrevParab.Axis(), AngTol)) + { + gp_Pnt P1 = ElCLib::Value(fpar, aParab); + gp_Pnt P2 = ElCLib::Value(lpar, aParab); + NewFpar = ElCLib::Parameter(PrevParab, P1); + NewLpar = ElCLib::Parameter(PrevParab, P2); + if (NewLpar < NewFpar) + { + Standard_Real MemNewFpar = NewFpar; + NewFpar = NewLpar; + NewLpar = MemNewFpar; + ConnectByOrigin = TopAbs::Reverse(ConnectByOrigin); + } + Done = Standard_True; + } + break; + } + } //end of switch (aType) + } // end of else if (aType == CurType && ... + if (Done) + { + if (NewFpar < FparSeq.Last()) + FparSeq(FparSeq.Length()) = NewFpar; + else + LparSeq(LparSeq.Length()) = NewLpar; + } + else + { + CurveSeq.Append(aCurve); + TopoDS_Shape aLocShape; + aLocShape.Location(aLoc); + aLocShape.Orientation(wexp.Orientation()); + LocSeq.Append(aLocShape); + FparSeq.Append(fpar); + LparSeq.Append(lpar); + TolSeq.Append(BRep_Tool::Tolerance(CurVertex)); + CurType = aType; + } + } // end of else (CurveSeq.IsEmpty()) -> not first time + } // end for (; wexp.More(); wexp.Next()) + + LastVertex = wexp.CurrentVertex(); + TolSeq.Append(BRep_Tool::Tolerance(LastVertex)); + + if (!CurveSeq.IsEmpty()) + { + Standard_Integer nb_curve = CurveSeq.Length(); //number of curves + TColGeom_Array1OfBSplineCurve tab(0,nb_curve-1); //array of the curves + TColStd_Array1OfReal tabtolvertex(0,nb_curve-1); //(0,nb_curve-2); //array of the tolerances + + Standard_Integer i; + + if (nb_curve > 1) + { + for (i = 1; i <= nb_curve; i++) + { + if (CurveSeq(i)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) + CurveSeq(i) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(i))))->BasisCurve(); + + Handle(Geom_TrimmedCurve) aTrCurve = new Geom_TrimmedCurve(CurveSeq(i), FparSeq(i), LparSeq(i)); + tab(i-1) = GeomConvert::CurveToBSplineCurve(aTrCurve); + tab(i-1)->Transform(LocSeq(i).Location().Transformation()); + GeomConvert::C0BSplineToC1BSplineCurve(tab(i-1), Precision::Confusion()); + if (LocSeq(i).Orientation() == TopAbs_REVERSED) + tab(i-1)->Reverse(); + + //Temporary + //char* name = new char[100]; + //sprintf(name, "c%d", i); + //DrawTrSurf::Set(name, tab(i-1)); + + if (i > 1) + tabtolvertex(i-2) = TolSeq(i-1); + } // end for (i = 1; i <= nb_curve; i++) + tabtolvertex(nb_curve-1) = TolSeq(TolSeq.Length()); + + Standard_Boolean closed_flag = Standard_False; + Standard_Real closed_tolerance = 0.; + if (FirstVertex.IsSame(LastVertex) && + GeomLProp::Continuity(tab(0), tab(nb_curve-1), + tab(0)->FirstParameter(), + tab(nb_curve-1)->LastParameter(), + Standard_False, Standard_False, LinTol, AngTol) >= GeomAbs_G1) + { + closed_flag = Standard_True ; + closed_tolerance = BRep_Tool::Tolerance(FirstVertex); + } + + Handle(TColGeom_HArray1OfBSplineCurve) concatcurve; //array of the concatenated curves + Handle(TColStd_HArray1OfInteger) ArrayOfIndices; //array of the remining Vertex + GeomConvert::ConcatC1(tab, + tabtolvertex, + ArrayOfIndices, + concatcurve, + closed_flag, + closed_tolerance); //C1 concatenation + + if (concatcurve->Length() > 1) + { + GeomConvert_CompCurveToBSplineCurve Concat(concatcurve->Value(concatcurve->Lower())); + + for (i = concatcurve->Lower()+1; i <= concatcurve->Upper(); i++) + Concat.Add( concatcurve->Value(i), LinTol, Standard_True ); + + concatcurve->SetValue(concatcurve->Lower(), Concat.BSplineCurve()); + } + + ResEdge = BRepLib_MakeEdge(concatcurve->Value(concatcurve->Lower()), + FirstVertex, LastVertex); + } + else + { + if (CurveSeq(1)->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) + CurveSeq(1) = (*((Handle(Geom_TrimmedCurve)*)&(CurveSeq(i))))->BasisCurve(); + + CurveSeq(1)->Transform(LocSeq(1).Location().Transformation()); + ResEdge = BRepLib_MakeEdge(CurveSeq(1), + FirstVertex, LastVertex, + FparSeq(1), LparSeq(1)); + } + } + + aShape = ResEdge; } if (aShape.IsNull()) return 0; @@ -298,7 +800,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const // Check shape validity BRepCheck_Analyzer ana (aShape, false); if (!ana.IsValid()) { - Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result"); + //Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result"); } aFunction->SetValue(aShape); @@ -326,10 +828,10 @@ Standard_EXPORT Handle_Standard_Type& GEOMImpl_ShapeDriver_Type_() static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL}; static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_ShapeDriver", - sizeof(GEOMImpl_ShapeDriver), - 1, - (Standard_Address)_Ancestors, - (Standard_Address)NULL); + sizeof(GEOMImpl_ShapeDriver), + 1, + (Standard_Address)_Ancestors, + (Standard_Address)NULL); return _aType; } @@ -348,5 +850,5 @@ const Handle(GEOMImpl_ShapeDriver) Handle(GEOMImpl_ShapeDriver)::DownCast(const } } - return _anOtherObject ; + return _anOtherObject; }