From: nbv Date: Wed, 5 Dec 2018 10:29:06 +0000 (+0300) Subject: Patches X-Git-Url: http://git.dev.opencascade.org/gitweb/?a=commitdiff_plain;h=1a1d20eece62a8c9d80be9a8aa17f65179ec36f1;p=occt-copy.git Patches --- diff --git a/src/BOPAlgo/BOPAlgo.msg b/src/BOPAlgo/BOPAlgo.msg index 67350fca88..673a39ec42 100644 --- a/src/BOPAlgo/BOPAlgo.msg +++ b/src/BOPAlgo/BOPAlgo.msg @@ -67,3 +67,12 @@ Warning: Removal of internal boundaries among Faces has failed .BOPAlgo_AlertRemovalOfIBForEdgesFailed Warning: Removal of internal boundaries among Edges has failed + +.BOPAlgo_AlertIntersectionOfPairOfShapesFailed +Warning: Intersection of pair of shapes has failed + +.BOPAlgo_AlertBuildingPCurveFailed +Warning: Building 2D curve of edge on face has failed + +.BOPAlgo_AlertAcquiredSelfIntersection +Warning: Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered diff --git a/src/BOPAlgo/BOPAlgo_Alerts.hxx b/src/BOPAlgo/BOPAlgo_Alerts.hxx index 02cec15f8f..04ce9c7b4f 100644 --- a/src/BOPAlgo/BOPAlgo_Alerts.hxx +++ b/src/BOPAlgo/BOPAlgo_Alerts.hxx @@ -78,4 +78,14 @@ DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertShellSplitterFailed) //! Some edges are too small and have no valid range DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertTooSmallEdge) +//! Intersection of pair of shapes has failed +DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertIntersectionOfPairOfShapesFailed) + +//! Building 2D curve of edge on face has failed +DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertBuildingPCurveFailed) + +//! Some sub-shapes of some of the argument become connected through +//! other shapes and the argument became self-interfered +DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertAcquiredSelfIntersection) + #endif // _BOPAlgo_Alerts_HeaderFile diff --git a/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx b/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx index c63a53875c..feec778809 100644 --- a/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx +++ b/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx @@ -69,4 +69,13 @@ static const char BOPAlgo_BOPAlgo_msg[] = "Warning: Removal of internal boundaries among Faces has failed\n" "\n" ".BOPAlgo_AlertRemovalOfIBForEdgesFailed\n" - "Warning: Removal of internal boundaries among Edges has failed\n"; + "Warning: Removal of internal boundaries among Edges has failed\n" + "\n" + ".BOPAlgo_AlertIntersectionOfPairOfShapesFailed\n" + "Warning: Intersection of pair of shapes has failed\n" + "\n" + ".BOPAlgo_AlertBuildingPCurveFailed\n" + "Warning: Building 2D curve of edge on face has failed\n" + "\n" + ".BOPAlgo_AlertAcquiredSelfIntersection\n" + "Warning: Some sub-shapes of some of the argument become connected through other shapes and the argument became self-interfered\n"; diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller.cxx index 5867221f5e..5c3b35cf92 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller.cxx @@ -294,6 +294,8 @@ void BOPAlgo_PaveFiller::PerformInternal() // UpdateBlocksWithSharedVertices(); // + myDS->RefineFaceInfoIn(); + // MakeSplitEdges(); if (HasErrors()) { return; diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller.hxx b/src/BOPAlgo/BOPAlgo_PaveFiller.hxx index ab79f4ec98..bd4e512fae 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller.hxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller.hxx @@ -87,13 +87,19 @@ class TopoDS_Face; //! - *Gluing options* - allows to speed up the calculation on the special //! cases, in which some sub-shapes are coincide.
//! -//! The algorithm returns the following Warning statuses:
-//! - *BOPAlgo_AlertSelfInterferingShape* - in case some of the argument shapes are self-interfering shapes;
-//! - *BOPAlgo_AlertTooSmallEdge* - in case some edges of the input shapes have no valid range;
+//! The algorithm returns the following Warning statuses: +//! - *BOPAlgo_AlertSelfInterferingShape* - in case some of the argument shapes are self-interfering shapes; +//! - *BOPAlgo_AlertTooSmallEdge* - in case some edges of the input shapes have no valid range; //! - *BOPAlgo_AlertNotSplittableEdge* - in case some edges of the input shapes has such a small -//! valid range so it cannot be split;
+//! valid range so it cannot be split; //! - *BOPAlgo_AlertBadPositioning* - in case the positioning of the input shapes leads to creation -//! of small edges.
+//! of small edges; +//! - *BOPAlgo_AlertIntersectionOfPairOfShapesFailed* - in case intersection of some of the +//! sub-shapes has failed; +//! - *BOPAlgo_AlertAcquiredSelfIntersection* - in case some sub-shapes of the argument become connected +//! through other shapes; +//! - *BOPAlgo_AlertBuildingPCurveFailed* - in case building 2D curve for some of the edges +//! on the faces has failed. //! //! The algorithm returns the following Error alerts: //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to @@ -290,6 +296,7 @@ protected: BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDMExEdges, BOPCol_DataMapOfIntegerInteger& theDMNewSD, const BOPCol_IndexedMapOfShape& theMicroEdges, + const BOPCol_IndexedMapOfShape& theVertsOnRejectedPB, const BOPCol_BaseAllocator& theAllocator); Standard_EXPORT void FindPaveBlocks (const Standard_Integer theV, const Standard_Integer theF, BOPDS_ListOfPaveBlock& theLPB); @@ -474,6 +481,8 @@ protected: //! In case self-interference is found the warning is added. Standard_EXPORT void CheckSelfInterference(); + //! Adds the warning about failed intersection of pair of sub-shapes + Standard_EXPORT void AddIntersectionFailedWarning(const TopoDS_Shape& theS1, const TopoDS_Shape& theS2); BOPCol_ListOfShape myArguments; BOPDS_PDS myDS; diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_11.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_11.cxx index c8341c5dd7..83faf2d126 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_11.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_11.cxx @@ -112,7 +112,8 @@ void BOPAlgo_PaveFiller::CheckSelfInterference() } // if (aLE.Extent() > 1) { - // Add warning + // Add the acquired self-interference warning: + // The same common block contains several edges from one argument TopoDS_Compound aWC; aBB.MakeCompound(aWC); // @@ -122,7 +123,7 @@ void BOPAlgo_PaveFiller::CheckSelfInterference() aBB.Add(aWC, aE1); } // - AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC)); + AddWarning (new BOPAlgo_AlertAcquiredSelfIntersection (aWC)); } } } @@ -168,7 +169,8 @@ void BOPAlgo_PaveFiller::CheckSelfInterference() for (j = 1; j <= aNbC; ++j) { const BOPCol_IndexedMapOfShape& aMCS = aMCSI(j); if (aMCS.Extent() > 1) { - // Add self-interference warning + // Add acquired self-interference warning: + // Several faces from one argument contain the same vertex or edge TopoDS_Compound aWC; aBB.MakeCompound(aWC); // @@ -177,7 +179,7 @@ void BOPAlgo_PaveFiller::CheckSelfInterference() const TopoDS_Shape& aSx = aMCS(iS); aBB.Add(aWC, aSx); } - AddWarning (new BOPAlgo_AlertSelfInterferingShape (aWC)); + AddWarning (new BOPAlgo_AlertAcquiredSelfIntersection (aWC)); } } } diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx index c4966683d9..9ac5e67ae7 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -110,7 +112,16 @@ class BOPAlgo_VertexEdge : public BOPAlgo_Algo { // virtual void Perform() { BOPAlgo_Algo::UserBreak(); - myFlag=myContext->ComputeVE (myV, myE, myT, myTolVNew, myFuzzyValue); + try + { + OCC_CATCH_SIGNALS + + myFlag=myContext->ComputeVE (myV, myE, myT, myTolVNew, myFuzzyValue); + } + catch (Standard_Failure) + { + AddError(new BOPAlgo_AlertIntersectionFailed); + } }; // protected: @@ -267,6 +278,11 @@ void BOPAlgo_PaveFiller::IntersectVE for (i = 0; i < aNbVE; ++i) { const BOPAlgo_VertexEdge& aVESolver = aVVE(i); if (aVESolver.Flag() != 0) { + if (aVESolver.HasErrors()) + { + // Warn about failed intersection of sub-shapes + AddIntersectionFailedWarning(aVESolver.Vertex(), aVESolver.Edge()); + } continue; } // @@ -491,3 +507,19 @@ void BOPAlgo_PaveFiller::SplitPaveBlocks(const BOPCol_MapOfInteger& theMEdges, } } } + +//======================================================================= +// function: AddIntersectionFailedWarning +// purpose: +//======================================================================= +void BOPAlgo_PaveFiller::AddIntersectionFailedWarning(const TopoDS_Shape& theS1, + const TopoDS_Shape& theS2) +{ + // Create the warn shape + TopoDS_Compound aWC; + BRep_Builder().MakeCompound(aWC); + BRep_Builder().Add(aWC, theS1); + BRep_Builder().Add(aWC, theS2); + // Add the warning + AddWarning(new BOPAlgo_AlertIntersectionOfPairOfShapesFailed(aWC)); +} \ No newline at end of file diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx index 3a8892e0be..5db97a8aff 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx @@ -93,7 +93,16 @@ class BOPAlgo_EdgeEdge : // virtual void Perform() { BOPAlgo_Algo::UserBreak(); - IntTools_EdgeEdge::Perform(); + try + { + OCC_CATCH_SIGNALS + + IntTools_EdgeEdge::Perform(); + } + catch (Standard_Failure) + { + AddError(new BOPAlgo_AlertIntersectionFailed); + } } // protected: @@ -229,7 +238,11 @@ void BOPAlgo_PaveFiller::PerformEE() Bnd_Box aBB1, aBB2; // BOPAlgo_EdgeEdge& anEdgeEdge=aVEdgeEdge(k); - if (!anEdgeEdge.IsDone()) { + if (!anEdgeEdge.IsDone() || anEdgeEdge.HasErrors()) { + // Warn about failed intersection of sub-shapes + const TopoDS_Shape& aE1 = myDS->Shape(anEdgeEdge.PaveBlock1()->OriginalEdge()); + const TopoDS_Shape& aE2 = myDS->Shape(anEdgeEdge.PaveBlock2()->OriginalEdge()); + AddIntersectionFailedWarning(aE1, aE2); continue; } // diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx index 291edb2de8..900d363bbb 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx @@ -17,6 +17,7 @@ #include +#include #include #include #include @@ -107,7 +108,16 @@ class BOPAlgo_VertexFace : public BOPAlgo_Algo { // virtual void Perform() { BOPAlgo_Algo::UserBreak(); - myFlag=myContext->ComputeVF(myV, myF, myT1, myT2, myTolVNew, myFuzzyValue); + try + { + OCC_CATCH_SIGNALS + + myFlag=myContext->ComputeVF(myV, myF, myT1, myT2, myTolVNew, myFuzzyValue); + } + catch (Standard_Failure) + { + AddError(new BOPAlgo_AlertIntersectionFailed); + } } // protected: @@ -212,7 +222,12 @@ void BOPAlgo_PaveFiller::PerformVF() const BOPAlgo_VertexFace& aVertexFace=aVVF(k); // iFlag=aVertexFace.Flag(); - if (iFlag) { + if (iFlag != 0) { + if (aVertexFace.HasErrors()) + { + // Warn about failed intersection of sub-shapes + AddIntersectionFailedWarning(aVertexFace.Vertex(), aVertexFace.Face()); + } continue; } // diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx index 84fc6d10d0..717e478920 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx @@ -103,7 +103,16 @@ class BOPAlgo_EdgeFace : // virtual void Perform() { BOPAlgo_Algo::UserBreak(); - IntTools_EdgeFace::Perform(); + try + { + OCC_CATCH_SIGNALS + + IntTools_EdgeFace::Perform(); + } + catch (Standard_Failure) + { + AddError(new BOPAlgo_AlertIntersectionFailed); + } } // protected: @@ -258,7 +267,9 @@ void BOPAlgo_PaveFiller::PerformEF() // for (k=0; k < aNbEdgeFace; ++k) { BOPAlgo_EdgeFace& aEdgeFace=aVEdgeFace(k); - if (!aEdgeFace.IsDone()) { + if (!aEdgeFace.IsDone() || aEdgeFace.HasErrors()) { + // Warn about failed intersection of sub-shapes + AddIntersectionFailedWarning(aEdgeFace.Edge(), aEdgeFace.Face()); continue; } // diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx index bbc1b35c91..dfbfe61954 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx @@ -144,7 +144,16 @@ class BOPAlgo_FaceFace : // virtual void Perform() { BOPAlgo_Algo::UserBreak(); - IntTools_FaceFace::Perform(myF1, myF2); + try + { + OCC_CATCH_SIGNALS + + IntTools_FaceFace::Perform(myF1, myF2); + } + catch (Standard_Failure) + { + AddError(new BOPAlgo_AlertIntersectionFailed); + } } // protected: @@ -263,10 +272,12 @@ void BOPAlgo_PaveFiller::PerformFF() for (k = 0; k < aNbFaceFace; ++k) { BOPAlgo_FaceFace& aFaceFace = aVFaceFace(k); aFaceFace.Indices(nF1, nF2); - if (!aFaceFace.IsDone()) { + if (!aFaceFace.IsDone() || aFaceFace.HasErrors()) { BOPDS_InterfFF& aFF = aFFs.Append1(); aFF.SetIndices(nF1, nF2); aFF.Init(0, 0); + // Warn about failed intersection of faces + AddIntersectionFailedWarning(aFaceFace.Face1(), aFaceFace.Face2()); continue; } // @@ -373,6 +384,7 @@ void BOPAlgo_PaveFiller::MakeBlocks() BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator); BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV; BOPCol_IndexedMapOfShape aMicroEdges(100, aAllocator); + BOPCol_IndexedMapOfShape aVertsOnRejectedPB; // for (i=0; iIndices(nVOut1, nVOut2); + if (nV1 != nVOut1 && nV1 != nVOut2 && !aMVBounds.Contains(nV1)) + { + aVertsOnRejectedPB.Add(aV1); + } + if (nV2 != nVOut1 && nV2 != nVOut2 && !aMVBounds.Contains(nV2)) + { + aVertsOnRejectedPB.Add(aV2); + } } } continue; @@ -639,7 +664,7 @@ void BOPAlgo_PaveFiller::MakeBlocks() // // post treatment MakeSDVerticesFF(aDMVLV, aDMNewSD); - PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aAllocator); + PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aVertsOnRejectedPB, aAllocator); if (HasErrors()) { return; } @@ -697,6 +722,7 @@ void BOPAlgo_PaveFiller::PostTreatFF BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges, BOPCol_DataMapOfIntegerInteger& aDMNewSD, const BOPCol_IndexedMapOfShape& theMicroEdges, + const BOPCol_IndexedMapOfShape& theVertsOnRejectedPB, const Handle(NCollection_BaseAllocator)& theAllocator) { Standard_Integer aNbS = theMSCPB.Extent(); @@ -724,8 +750,9 @@ void BOPAlgo_PaveFiller::PostTreatFF BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF(); // Standard_Integer aNbME = theMicroEdges.Extent(); + Standard_Integer aNbVOnRPB = theVertsOnRejectedPB.Extent(); // 0 - if (aNbS==1 && (aNbME == 0)) { + if (aNbS==1 && (aNbME == 0) && (aNbVOnRPB == 0)) { const TopoDS_Shape& aS=theMSCPB.FindKey(1); const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1); // @@ -824,6 +851,20 @@ void BOPAlgo_PaveFiller::PostTreatFF aBB.UpdateVertex(aVerts[1], aTolV2 + aDist); } } + + // Add vertices put on the real section curves to unify them with the + // vertices of the edges, by which these sections curves have been rejected + for (Standard_Integer i = 1; i <= aNbVOnRPB; ++i) + { + TopoDS_Shape aVer = theVertsOnRejectedPB(i); + Standard_Integer iVer = myDS->Index(aVer); + const Standard_Integer* pSD = aDMNewSD.Seek(iVer); + if (pSD) + aVer = myDS->Shape(*pSD); + + if (anAddedSD.Add(aVer)) + aLS.Append(aVer); + } // // 2 Fuse shapes aPF.SetProgressIndicator(myProgressIndicator); diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx index bf02175998..1e91f5529a 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx @@ -16,6 +16,7 @@ // commercial license or contractual agreement. #include +#include #include #include #include @@ -241,28 +242,37 @@ class BOPAlgo_MPC : public BOPAlgo_Algo { } // virtual void Perform() { - Standard_Integer iErr; - // - iErr=1; - if (!myEz.IsNull()) { - TopoDS_Edge aSpz; + try + { + OCC_CATCH_SIGNALS + + Standard_Integer iErr; // - BOPTools_AlgoTools::MakeSplitEdge(myEz,myV1, myT1, - myV2, myT2, aSpz); + iErr=1; + if (!myEz.IsNull()) { + TopoDS_Edge aSpz; + // + BOPTools_AlgoTools::MakeSplitEdge(myEz,myV1, myT1, + myV2, myT2, aSpz); + // + iErr= + BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz, + myE, + myF, + myContext); + } // - iErr= - BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz, - myE, - myF, - myContext); - } - // - if (iErr) { - BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF, myContext); + if (iErr) { + BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF, myContext); + } + // + if (myFlag) { + UpdateVertices(myE, myF); + } } - // - if (myFlag) { - UpdateVertices(myE, myF); + catch (Standard_Failure) + { + AddError(new BOPAlgo_AlertBuildingPCurveFailed(TopoDS_Shape())); } } // @@ -676,6 +686,20 @@ void BOPAlgo_PaveFiller::MakePCurves() //====================================================== BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext); //====================================================== + + // Add warnings of the failed projections + Standard_Integer aNb = aVMPC.Extent(); + for (i = 0; i < aNb; ++i) + { + if (aVMPC(i).HasErrors()) + { + TopoDS_Compound aWC; + BRep_Builder().MakeCompound(aWC); + BRep_Builder().Add(aWC, aVMPC(i).Edge()); + BRep_Builder().Add(aWC, aVMPC(i).Face()); + AddWarning(new BOPAlgo_AlertBuildingPCurveFailed(aWC)); + } + } } //======================================================================= //function : UpdateVertices diff --git a/src/BOPDS/BOPDS_DS.cxx b/src/BOPDS/BOPDS_DS.cxx index c89f7a31b9..58bbe6d79f 100644 --- a/src/BOPDS/BOPDS_DS.cxx +++ b/src/BOPDS/BOPDS_DS.cxx @@ -1418,6 +1418,44 @@ void BOPDS_DS::RefineFaceInfoOn() } } } + +//======================================================================= +//function : RefineFaceInfoIn +//purpose : +//======================================================================= +void BOPDS_DS::RefineFaceInfoIn() +{ + for (Standard_Integer i = 0; i < myNbSourceShapes; ++i) + { + const BOPDS_ShapeInfo& aSI = ShapeInfo(i); + if (aSI.ShapeType() != TopAbs_FACE) + continue; + + if (!aSI.HasReference()) + continue; + + BOPDS_FaceInfo& aFI = ChangeFaceInfo(i); + + const BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.PaveBlocksOn(); + BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn(); + + if (aMPBIn.IsEmpty() || aMPBOn.IsEmpty()) + continue; + + BOPDS_IndexedMapOfPaveBlock aMPBInNew; + + const Standard_Integer aNbPBIn = aMPBIn.Extent(); + for (Standard_Integer j = 1; j <= aNbPBIn; ++j) + { + if (!aMPBOn.Contains(aMPBIn(j))) + aMPBInNew.Add(aMPBIn(j)); + } + + if (aMPBInNew.Extent() < aNbPBIn) + aMPBIn = aMPBInNew; + } +} + //======================================================================= //function : AloneVertices //purpose : diff --git a/src/BOPDS/BOPDS_DS.hxx b/src/BOPDS/BOPDS_DS.hxx index 6b19debd0e..276c15961a 100644 --- a/src/BOPDS/BOPDS_DS.hxx +++ b/src/BOPDS/BOPDS_DS.hxx @@ -302,6 +302,9 @@ Standard_EXPORT virtual ~BOPDS_DS(); //! ++ Standard_EXPORT void RefineFaceInfoOn(); + //! Removes faces with state ON from the + //! list of IN-faces + Standard_EXPORT void RefineFaceInfoIn(); //! Returns information about ON/IN subshapes of the given faces. //! @param theMVOnIn the indices of ON/IN vertices from both faces diff --git a/src/BOPTest/BOPTest_CheckCommands.cxx b/src/BOPTest/BOPTest_CheckCommands.cxx index 618e86cda4..77d5cd2a44 100644 --- a/src/BOPTest/BOPTest_CheckCommands.cxx +++ b/src/BOPTest/BOPTest_CheckCommands.cxx @@ -235,6 +235,8 @@ Standard_Integer bopcheck (Draw_Interpretor& di, // aTimer.Stop(); // + BOPTest::ReportAlerts(aChecker); + // iErr=aChecker.HasErrors(); // const BOPDS_DS& aDS=*(aChecker.PDS()); diff --git a/src/BOPTools/BOPTools_AlgoTools2D.cxx b/src/BOPTools/BOPTools_AlgoTools2D.cxx index 9697b92f56..2696de0e4e 100644 --- a/src/BOPTools/BOPTools_AlgoTools2D.cxx +++ b/src/BOPTools/BOPTools_AlgoTools2D.cxx @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -667,12 +668,25 @@ void BOPTools_AlgoTools2D::MakePCurveOnFace } // TolReached2d=aTolR; - // + + // Adjust curve for periodic surface Handle(Geom2d_Curve) aC2DA; BOPTools_AlgoTools2D::AdjustPCurveOnSurf (*pBAS, aT1, aT2, aC2D, aC2DA); - // - aC2D=aC2DA; - // + aC2D = aC2DA; + + // Make sure that the range of the 2D curve is sufficient for representation of the 3D curve. + Standard_Real aTCFirst = aC2D->FirstParameter(); + Standard_Real aTCLast = aC2D->LastParameter(); + if ((aTCFirst - aT1) > Precision::PConfusion() || + (aT2 - aTCLast ) > Precision::PConfusion()) + { + if (aTCFirst < aT1) aTCFirst = aT1; + if (aTCLast > aT2) aTCLast = aT2; + + GeomLib::SameRange(Precision::PConfusion(), aC2D, + aTCFirst, aTCLast, aT1, aT2, aC2D); + } + // compute the appropriate tolerance for the edge Handle(Geom_Surface) aS = pBAS->Surface().Surface(); aS = Handle(Geom_Surface)::DownCast(aS->Transformed(pBAS->Trsf())); diff --git a/src/BRepFill/BRepFill_Pipe.cxx b/src/BRepFill/BRepFill_Pipe.cxx index c514052544..db46764d7a 100644 --- a/src/BRepFill/BRepFill_Pipe.cxx +++ b/src/BRepFill/BRepFill_Pipe.cxx @@ -102,40 +102,6 @@ static Standard_Boolean UpdateMap(const TopoDS_Shape& theKey, return !found; } -static void ReverseModifiedEdges(TopoDS_Shape& aShape, - TopTools_MapOfShape& Emap) -{ - TopExp_Explorer Explo(aShape, TopAbs_FACE); - BRep_Builder BB; - - for (; Explo.More(); Explo.Next()) - { - TopoDS_Shape aFace = Explo.Current(); - TopoDS_Iterator itf(aFace); - for (; itf.More(); itf.Next()) - { - TopoDS_Shape aWire = itf.Value(); - TopTools_ListOfShape Ledges; - TopoDS_Iterator itw(aWire); - for (; itw.More(); itw.Next()) - Ledges.Append(itw.Value()); - - aWire.Free(Standard_True); - TopTools_ListIteratorOfListOfShape itl(Ledges); - for (; itl.More(); itl.Next()) - BB.Remove(aWire, itl.Value()); - - for (itl.Initialize(Ledges); itl.More(); itl.Next()) - { - TopoDS_Shape anEdge = itl.Value(); - if (Emap.Contains(anEdge)) - anEdge.Reverse(); - BB.Add(aWire, anEdge); - } - } - } -} - static void UpdateTolFromTopOrBottomPCurve(const TopoDS_Face& aFace, TopoDS_Edge& anEdge) { @@ -739,9 +705,6 @@ TopoDS_Shape BRepFill_Pipe::MakeShape(const TopoDS_Shape& S, result = MkSw.Shape(); UpdateMap(TheS.Located(myProfile.Location()), result, myGenMap); myErrorOnSurf = MkSw.ErrorOnSurface(); - //Correct and - ReverseModifiedEdges(myFirst, myReversedEdges); - ReverseModifiedEdges(myLast, myReversedEdges); // Labeling of elements if (mySections.IsNull()) { diff --git a/src/BRepFill/BRepFill_PipeShell.cxx b/src/BRepFill/BRepFill_PipeShell.cxx index 519c6b5d0b..3d0eba45f8 100644 --- a/src/BRepFill/BRepFill_PipeShell.cxx +++ b/src/BRepFill/BRepFill_PipeShell.cxx @@ -583,28 +583,15 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1) //======================================================================= void BRepFill_PipeShell::DeleteProfile(const TopoDS_Shape& Profile) { - Standard_Boolean isVertex = (Profile.ShapeType() == TopAbs_VERTEX); - Standard_Boolean Trouve=Standard_False; Standard_Integer ii; for (ii=1; ii<=mySeq.Length() && !Trouve; ii++) { - Standard_Boolean found = Standard_False; - const TopoDS_Wire& aWire = mySeq.Value(ii).Wire(); - if (isVertex) - { - TopExp_Explorer Explo(aWire, TopAbs_VERTEX); - for (; Explo.More(); Explo.Next()) - if (Profile.IsSame(Explo.Current())) - found = Standard_True; - } - else if (Profile.IsSame(aWire)) - found = Standard_True; - - if (found) - { - Trouve = Standard_True; - mySeq.Remove(ii); - } + const TopoDS_Shape& aSection = mySeq.Value(ii).OriginalShape(); + if (Profile.IsSame(aSection)) + { + Trouve = Standard_True; + mySeq.Remove(ii); + } } if (Trouve) mySection.Nullify(); @@ -705,7 +692,7 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1) //function : Build //purpose : Construct the Shell and the history //======================================================================= - Standard_Boolean BRepFill_PipeShell::Build() + Standard_Boolean BRepFill_PipeShell::Build() { Standard_Boolean Ok; Standard_Real FirstS, LastS; @@ -759,8 +746,9 @@ void BRepFill_PipeShell::SetForceApproxC1(const Standard_Boolean ForceApproxC1) MkSw.SetTolerance(myTol3d, myBoundTol, 1.e-5, myTolAngular); MkSw.SetAngularControl(angmin, angmax); MkSw.SetForceApproxC1(myForceApproxC1); - MkSw.SetBounds(TopoDS::Wire(myFirst), - TopoDS::Wire(myLast)); + MkSw.SetBounds(TopoDS::Wire(myFirst), + TopoDS::Wire(myLast)); + GeomAbs_Shape theContinuity = GeomAbs_C2; if (myTrihedron == GeomFill_IsDiscreteTrihedron) theContinuity = GeomAbs_C0; @@ -914,13 +902,9 @@ const TopoDS_Shape& BRepFill_PipeShell::LastShape() const //function : Generated //purpose : //======================================================================= -// void BRepFill_PipeShell::Generated(const TopoDS_Shape& , -// TopTools_ListOfShape& ) void BRepFill_PipeShell::Generated(const TopoDS_Shape& theShape, TopTools_ListOfShape& theList) { - // throw Standard_NotImplemented("Generated:Pas Fait"); - theList.Clear(); if(myGenMap.IsBound(theShape)) { @@ -1197,9 +1181,6 @@ void BRepFill_PipeShell::Place(const BRepFill_Section& Sec, Sec.WithCorrection()); TopoDS_Wire TmpWire = Sec.Wire(); aTrsf = Place.Transformation(); - //TopLoc_Location Loc2(Place.Transformation()), Loc1; - //Loc1 = TmpWire.Location(); - //W.Location(Loc2.Multiplied(Loc1)); //Transform the copy W = TopoDS::Wire(BRepBuilderAPI_Transform(TmpWire, aTrsf, Standard_True)); //////////////////////////////////// @@ -1240,37 +1221,40 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep) TopoDS_Iterator itw; for (indw = 1; indw <= mySeq.Length(); indw++) { - const TopoDS_Wire& aSection = mySeq(indw).Wire(); + const TopoDS_Shape& Section = mySeq(indw).OriginalShape(); + TopoDS_Wire aSection; Standard_Boolean IsPunctual = mySeq(indw).IsPunctual(); if (IsPunctual) { //for punctual sections (first or last) //we take all the wires generated along the path - TopExp_Explorer Explo(aSection, TopAbs_VERTEX); - const TopoDS_Shape& VerSection = Explo.Current(); + TopTools_ListOfShape Elist; for (Standard_Integer i = 1; i <= anUEdges->UpperRow(); i++) for (Standard_Integer j = 1; j <= anUEdges->UpperCol(); j++) Elist.Append(anUEdges->Value(i,j)); - myGenMap.Bind(VerSection, Elist); + myGenMap.Bind(Section, Elist); continue; } + else + aSection = TopoDS::Wire(Section); //Take the real index of section on the path Standard_Integer IndOfW = myIndOfSec(indw); const TopoDS_Wire& theWire = TopoDS::Wire(WSeq(IndOfW)); BRepTools_WireExplorer wexp_sec(aSection); for (inde = 1; wexp_sec.More(); wexp_sec.Next()) { - const TopoDS_Edge& anEdge = TopoDS::Edge(wexp_sec.Current()); + const TopoDS_Edge& anOriginalEdge = TopoDS::Edge(wexp_sec.Current()); + TopoDS_Edge anEdge = TopoDS::Edge(mySeq(indw).ModifiedShape(anOriginalEdge)); if (BRep_Tool::Degenerated(anEdge)) continue; TopoDS_Shell aShell; BB.MakeShell(aShell); TopoDS_Vertex aVertex [2]; - TopExp::Vertices(anEdge, aVertex[0], aVertex[1]); + TopExp::Vertices(anOriginalEdge, aVertex[0], aVertex[1]); Standard_Integer SignOfAnEdge = - (anEdge.Orientation() == TopAbs_FORWARD)? 1 : -1; + (anOriginalEdge.Orientation() == TopAbs_FORWARD)? 1 : -1; //For each non-degenerated inde-th edge of //we find inde-th edge in @@ -1422,7 +1406,7 @@ void BRepFill_PipeShell::BuildHistory(const BRepFill_Sweep& theSweep) TopTools_ListOfShape ListShell; ListShell.Append(aShell); - myGenMap.Bind(anEdge, ListShell); + myGenMap.Bind(anOriginalEdge, ListShell); //////////////////////// inde++; diff --git a/src/BRepFill/BRepFill_PipeShell.hxx b/src/BRepFill/BRepFill_PipeShell.hxx index c99ab7e758..36d6c824a0 100644 --- a/src/BRepFill/BRepFill_PipeShell.hxx +++ b/src/BRepFill/BRepFill_PipeShell.hxx @@ -168,6 +168,10 @@ public: Standard_EXPORT void Simulate (const Standard_Integer NumberOfSection, TopTools_ListOfShape& Sections); //! Builds the resulting shape (redefined from MakeShape). + //! If theIsToCheckValidity == FALSE then BRepFill_Sweep algorithm + //! is allowed to create invalid faces (having self-interferences). + //! It is considered for them that such faces will be processed and + //! fixed by the high-level algorithms Standard_EXPORT Standard_Boolean Build(); //! Transform the sweeping Shell in Solid. diff --git a/src/BRepFill/BRepFill_Section.cxx b/src/BRepFill/BRepFill_Section.cxx index b65b5f85c1..09e5d6f8a7 100644 --- a/src/BRepFill/BRepFill_Section.cxx +++ b/src/BRepFill/BRepFill_Section.cxx @@ -22,6 +22,9 @@ #include #include #include +#include +#include +#include BRepFill_Section::BRepFill_Section() :islaw(0), ispunctual(0), @@ -41,12 +44,19 @@ BRepFill_Section::BRepFill_Section(const TopoDS_Shape& Profile, contact(WithContact), correction(WithCorrection) { - if (Profile.ShapeType() == TopAbs_WIRE) - wire = TopoDS::Wire(Profile); - else if (Profile.ShapeType() == TopAbs_VERTEX) + myOriginalShape = Profile; + + ShapeUpgrade_RemoveLocations RemLoc; + RemLoc.SetRemoveLevel(TopAbs_COMPOUND); + RemLoc.Remove(Profile); + TopoDS_Shape aProfile = RemLoc.GetResult(); + + if (aProfile.ShapeType() == TopAbs_WIRE) + wire = TopoDS::Wire(aProfile); + else if (aProfile.ShapeType() == TopAbs_VERTEX) { ispunctual = Standard_True; - TopoDS_Vertex aVertex = TopoDS::Vertex(Profile); + TopoDS_Vertex aVertex = TopoDS::Vertex(aProfile); BRep_Builder BB; TopoDS_Edge DegEdge; @@ -67,3 +77,58 @@ void BRepFill_Section::Set(const Standard_Boolean IsLaw) { islaw = IsLaw; } + +TopoDS_Shape BRepFill_Section::ModifiedShape(const TopoDS_Shape& theShape) const +{ + TopoDS_Shape aModifiedShape; + + switch (theShape.ShapeType()) + { + case TopAbs_WIRE: + if (theShape.IsSame(myOriginalShape)) + aModifiedShape = wire; + break; + case TopAbs_EDGE: + { + TopoDS_Iterator itor(myOriginalShape); + TopoDS_Iterator itw(wire); + for (; itor.More(); itor.Next(),itw.Next()) + { + const TopoDS_Shape& anOriginalEdge = itor.Value(); + const TopoDS_Shape& anEdge = itw.Value(); + if (anOriginalEdge.IsSame(theShape)) + { + aModifiedShape = anEdge; + break; + } + } + } + break; + case TopAbs_VERTEX: + if (theShape.IsSame(myOriginalShape)) + { + TopExp_Explorer Explo(wire, TopAbs_VERTEX); + aModifiedShape = Explo.Current(); + } + else + { + TopExp_Explorer ExpOrig(myOriginalShape, TopAbs_VERTEX); + TopExp_Explorer ExpWire(wire, TopAbs_VERTEX); + for (; ExpOrig.More(); ExpOrig.Next(),ExpWire.Next()) + { + const TopoDS_Shape& anOriginalVertex = ExpOrig.Current(); + const TopoDS_Shape& aVertex = ExpWire.Current(); + if (anOriginalVertex.IsSame(theShape)) + { + aModifiedShape = aVertex; + break; + } + } + } + break; + default: + break; + } + + return aModifiedShape; +} diff --git a/src/BRepFill/BRepFill_Section.hxx b/src/BRepFill/BRepFill_Section.hxx index ede9091f05..10acf1decc 100644 --- a/src/BRepFill/BRepFill_Section.hxx +++ b/src/BRepFill/BRepFill_Section.hxx @@ -43,10 +43,14 @@ public: Standard_EXPORT void Set (const Standard_Boolean IsLaw); + const TopoDS_Shape& OriginalShape() const; + const TopoDS_Wire& Wire() const; const TopoDS_Vertex& Vertex() const; + Standard_EXPORT TopoDS_Shape ModifiedShape(const TopoDS_Shape& theShape) const; + Standard_Boolean IsLaw() const; Standard_Boolean IsPunctual() const; @@ -68,6 +72,7 @@ private: + TopoDS_Shape myOriginalShape; TopoDS_Wire wire; TopoDS_Vertex vertex; Standard_Boolean islaw; diff --git a/src/BRepFill/BRepFill_Section.lxx b/src/BRepFill/BRepFill_Section.lxx index 5b80bc996e..c96eaec01f 100644 --- a/src/BRepFill/BRepFill_Section.lxx +++ b/src/BRepFill/BRepFill_Section.lxx @@ -14,6 +14,11 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +inline const TopoDS_Shape& BRepFill_Section::OriginalShape() const +{ + return myOriginalShape; +} + inline const TopoDS_Wire& BRepFill_Section::Wire() const { return wire; diff --git a/src/BRepFill/BRepFill_Sweep.cxx b/src/BRepFill/BRepFill_Sweep.cxx index 9e35334bbb..1d2f0214b3 100644 --- a/src/BRepFill/BRepFill_Sweep.cxx +++ b/src/BRepFill/BRepFill_Sweep.cxx @@ -366,6 +366,56 @@ static Standard_Boolean SameParameter(TopoDS_Edge& E, return Standard_True; } +static void CorrectSameParameter(TopoDS_Edge& theEdge, + const TopoDS_Face& theFace1, + const TopoDS_Face& theFace2) +{ + if (BRep_Tool::Degenerated(theEdge)) + return; + + Standard_Real fpar, lpar; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, fpar, lpar); + + Standard_Boolean PCurveExists [2] = {Standard_False, Standard_False}; + BRepAdaptor_Curve BAcurve [2]; + + if (!theFace1.IsNull()) + { + PCurveExists[0] = Standard_True; + BAcurve[0].Initialize(theEdge, theFace1); + } + if (!theFace1.IsNull() && + theFace1.IsSame(theFace2)) + theEdge.Reverse(); + if (!theFace2.IsNull()) + { + PCurveExists[1] = Standard_True; + BAcurve[1].Initialize(theEdge, theFace2); + } + + Standard_Real MaxSqDist = 0.; + const Standard_Integer NCONTROL = 23; + Standard_Real delta = (lpar - fpar)/NCONTROL; + + for (Standard_Integer i = 0; i <= NCONTROL; i++) + { + Standard_Real aParam = fpar + i*delta; + gp_Pnt aPnt = aCurve->Value(aParam); + for (Standard_Integer j = 0; j < 2; j++) + if (PCurveExists[j]) + { + gp_Pnt aPntFromFace = BAcurve[j].Value(aParam); + Standard_Real aSqDist = aPnt.SquareDistance(aPntFromFace); + if (aSqDist > MaxSqDist) + MaxSqDist = aSqDist; + } + } + + Standard_Real aTol = sqrt(MaxSqDist); + BRep_Builder BB; + BB.UpdateEdge(theEdge, aTol); +} + //======================================================================= //Objet : Orientate an edge of natural restriction // : General @@ -666,7 +716,7 @@ static TopoDS_Edge BuildEdge(Handle(Geom_Curve)& C3d, // P2 = BT.Pnt(VL); P2 = BRep_Tool::Pnt(VL); // Tol2 = BT.Tolerance(VF); - Tol2 = BRep_Tool::Tolerance(VF); + Tol2 = BRep_Tool::Tolerance(VL); Tol = Max(Tol1, Tol2); if (VF.IsSame(VL) || @@ -809,24 +859,44 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF, Prof1 = BRep_Tool::Curve(E1, f1, l1); // Prof2 = BT.Curve(E2, f2, l2); Prof2 = BRep_Tool::Curve(E2, f2, l2); + + // Indeed, both Prof1 and Prof2 are the same curves but in different positions + gp_Pnt P1, P2, P; - gp_Pnt2d p1, p2; - gp_Trsf Tf; - Tf.SetTransformation(Axe); - -// Choose the angle of opening - P1 = Prof1->Value((f1+l1)/2); - P2 = Prof2->Value((f2+l2)/2); - P1.Transform(Tf); - P2.Transform(Tf); - p1.SetCoord(P1.Z(), P1.X()); - p2.SetCoord(P2.Z(), P2.X()); - gp_Vec2d v1(gp::Origin2d(), p1); - gp_Vec2d v2(gp::Origin2d(), p2); - if (v1.Magnitude() <= gp::Resolution() || - v2.Magnitude() <= gp::Resolution()) + + // Choose the angle of opening + gp_Trsf aTf; + aTf.SetTransformation(Axe); + + // Choose the furthest point from the "center of revolution" + // to provide correct angle measurement. + const Standard_Real aPrm[] = {f1, 0.5*(f1 + l1), l1}; + const gp_Pnt aP1[] = {Prof1->Value(aPrm[0]).Transformed(aTf), + Prof1->Value(aPrm[1]).Transformed(aTf), + Prof1->Value(aPrm[2]).Transformed(aTf)}; + + Standard_Integer aMaxIdx = -1; + Standard_Real aMaxDist = RealFirst(); + for (Standard_Integer i = 0; i < 3; i++) + { + const Standard_Real aDist = aP1[i].X()*aP1[i].X() + aP1[i].Z()*aP1[i].Z(); + if (aDist > aMaxDist) + { + aMaxDist = aDist; + aMaxIdx = i; + } + } + + const gp_Pnt aP2 = Prof2->Value(aPrm[aMaxIdx]).Transformed(aTf); + const gp_Vec2d aV1(aP1[aMaxIdx].Z(), aP1[aMaxIdx].X()); + const gp_Vec2d aV2(aP2.Z(), aP2.X()); + if (aV1.SquareMagnitude() <= gp::Resolution() || + aV2.SquareMagnitude() <= gp::Resolution()) + { return Standard_False; - Angle = v1.Angle(v2); + } + + Angle = aV1.Angle(aV2); gp_Ax1 axe(Axe.Location(), Axe.YDirection()); @@ -837,14 +907,14 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF, Handle(Geom_SurfaceOfRevolution) Rev = new (Geom_SurfaceOfRevolution) (Prof1, axe); - + Handle(Geom_Surface) Surf = new (Geom_RectangularTrimmedSurface) (Rev, 0, Angle, f1, l1); // Control the direction of the rotation Standard_Boolean ToReverseResult = Standard_False; gp_Vec d1u; - d1u = Surf->DN(0, (f1+l1)/2, 1, 0); + d1u = Surf->DN(0, aPrm[aMaxIdx], 1, 0); if (d1u.Angle(TangentOnPart1) > M_PI/2) { //Invert everything ToReverseResult = Standard_True; /* @@ -1135,19 +1205,40 @@ static Standard_Boolean Filling(const TopoDS_Shape& EF, B.MakeEdge(Aux2); // Set the orientation - gp_Vec D1U, D1V, N1, N2; - C1->D0( (f1+l1)/2, P2d); - Surf->D1(P2d.X(), P2d.Y(), P, D1U, D1V); - N1 = D1U^D1V; - -// C1 = BT.CurveOnSurface(E1, TopoDS::Face(F1), f2, l2); - C1 = BRep_Tool::CurveOnSurface(E1, TopoDS::Face(F1), f2, l2); - C1->D0( (f1+l1)/2, P2d); - Handle(BRepAdaptor_HSurface) AS = new BRepAdaptor_HSurface(TopoDS::Face(F1)); - AS->D1(P2d.X(), P2d.Y(), P, D1U, D1V); - N2 = D1U^D1V; + + // Provide correct normals computation + // (the normal will be computed not in + // singularity point definitely). + Angle = RealFirst(); + for (Standard_Integer i = 0; i < 3; i++) + { + gp_Vec D1U, D1V, N1, N2; + C1->D0(aPrm[i], P2d); + Surf->D1(P2d.X(), P2d.Y(), P, D1U, D1V); + N1 = D1U^D1V; + + if (N1.SquareMagnitude() < Precision::SquareConfusion()) + continue; + + // C1 = BT.CurveOnSurface(E1, TopoDS::Face(F1), f2, l2); + C1 = BRep_Tool::CurveOnSurface(E1, TopoDS::Face(F1), f2, l2); + C1->D0(aPrm[i], P2d); + Handle(BRepAdaptor_HSurface) AS = new BRepAdaptor_HSurface(TopoDS::Face(F1)); + AS->D1(P2d.X(), P2d.Y(), P, D1U, D1V); + N2 = D1U^D1V; + + if (N2.SquareMagnitude() < Precision::SquareConfusion()) + continue; + + Angle = N1.Angle(N2); + + break; + } - if ( (F1.Orientation() == TopAbs_REVERSED) ^ (N1.Angle(N2)>M_PI/2) ) + if (Angle == RealFirst()) + return Standard_False; + + if ( (F1.Orientation() == TopAbs_REVERSED) ^ (Angle>M_PI/2)) Result.Orientation(TopAbs_REVERSED); else Result.Orientation(TopAbs_FORWARD); @@ -1661,6 +1752,60 @@ static Standard_Boolean IsDegen(const Handle(Geom_Surface)& S, return B; } +static void ReverseEdgeInFirstOrLastWire(TopoDS_Shape& theWire, + const TopoDS_Shape& theEdge) +{ + TopoDS_Shape EdgeToReverse; + TopoDS_Iterator itw(theWire); + + for (; itw.More(); itw.Next()) + { + const TopoDS_Shape& anEdge = itw.Value(); + if (anEdge.IsSame(theEdge)) + { + EdgeToReverse = anEdge; + break; + } + } + + if (!EdgeToReverse.IsNull()) + { + BRep_Builder BB; + theWire.Free(Standard_True); + BB.Remove(theWire, EdgeToReverse); + EdgeToReverse.Reverse(); + BB.Add(theWire, EdgeToReverse); + } +} + +static void ReverseModifiedEdges(TopoDS_Wire& theWire, + const TopTools_MapOfShape& theEmap) +{ + if (theEmap.IsEmpty()) + return; + + TopoDS_Iterator itw(theWire); + BRep_Builder BB; + + TopTools_ListOfShape Ledges; + for (; itw.More(); itw.Next()) + Ledges.Append(itw.Value()); + + theWire.Free(Standard_True); + TopTools_ListIteratorOfListOfShape itl(Ledges); + for (; itl.More(); itl.Next()) + BB.Remove(theWire, itl.Value()); + + for (itl.Initialize(Ledges); itl.More(); itl.Next()) + { + TopoDS_Shape anEdge = itl.Value(); + if (theEmap.Contains(anEdge)) + anEdge.Reverse(); + BB.Add(theWire, anEdge); + } +} + + //======================================================================= //function : Constructeur //purpose : @@ -1670,8 +1815,6 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, const Standard_Boolean WithKPart) : isDone(Standard_False), KPart(WithKPart) - - { mySec = Section; myLoc = Location; @@ -1947,11 +2090,12 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, BRep_Builder B; Standard_Integer NbPath = ILast - IFirst; Standard_Integer NbLaw = mySec->NbLaw(); - Standard_Boolean uclose, vclose, constSection, hasdegen = Standard_False; + Standard_Boolean uclose, vclose, global_vclose, constSection, hasdegen = Standard_False; constSection = mySec->IsConstant(); uclose = mySec->IsUClosed(); vclose = (mySec->IsVClosed() && myLoc->IsClosed()) && (NbPath == myLoc->NbLaw()) && (myLoc->IsG1(0, myTol3d)>= 0); + global_vclose = (myLoc->IsClosed()) && (myLoc->IsG1(0, myTol3d)>= 0); Error = 0.; // (1) Construction of all surfaces @@ -2064,6 +2208,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, Standard_Boolean exuv, singu, singv; Handle(Geom_Surface) S; + //Correct and : reverse modified edges + ReverseModifiedEdges(FirstShape, ReversedEdges); + ReverseModifiedEdges(LastShape, ReversedEdges); + // (2.0) return preexisting Edges and vertices TopoDS_Edge E; TColStd_Array1OfBoolean IsBuilt(1, NbLaw); @@ -2293,7 +2441,6 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, // ---------- Creation of Vertex and edge ------------ - ReversedEdges.Clear(); for (ipath=1, IPath=IFirst; ipath<=NbPath; ipath++, IPath++) { for (isec=1; isec <=NbLaw; isec++) { @@ -2496,7 +2643,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, TopoDS::Edge(VEdge(isec, ipath)), ReversedEdges); if (ReversedEdges.Contains(VEdge(isec, ipath))) + { + ReverseEdgeInFirstOrLastWire(FirstShape, VEdge(isec, ipath)); StartEdges(isec).Reverse(); + } } } @@ -2524,7 +2674,10 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, myTol3d); else { - if (ipath != NbPath || vclose) + if (ipath != NbPath || + vclose || + (global_vclose && ILast == myLoc->NbLaw()+1)) + UpdateEdge(TopoDS::Edge(VEdge(isec, ipath+1)), S, exuv, VLast); else //ipath == NbPath && !vclose => rebuild last edge @@ -2536,6 +2689,8 @@ BRepFill_Sweep::BRepFill_Sweep(const Handle(BRepFill_SectionLaw)& Section, RebuildTopOrBottomEdge(aNewLastEdge, TopoDS::Edge(VEdge(isec, ipath+1)), ReversedEdges); + if (ReversedEdges.Contains(VEdge(isec, ipath+1))) + ReverseEdgeInFirstOrLastWire(LastShape, VEdge(isec, ipath+1)); } } } @@ -2877,6 +3032,30 @@ void BRepFill_Sweep::Build(TopTools_MapOfShape& ReversedEdges, } } + //Ensure Same Parameter on U-edges + for (ii = myUEdges->LowerRow(); ii <= myUEdges->UpperRow(); ii++) + { + if (mySec->IsUClosed() && ii == myUEdges->UpperRow()) + continue; + for (jj = myUEdges->LowerCol(); jj <= myUEdges->UpperCol(); jj++) + { + TopoDS_Edge anEdge = TopoDS::Edge(myUEdges->Value(ii, jj)); + if (anEdge.IsNull()) + continue; + TopoDS_Face Face1, Face2; + Standard_Integer i1 = ii-1, i2 = ii; + if (i1 == 0 && mySec->IsUClosed()) + i1 = myFaces->UpperRow(); + if (i2 > myFaces->UpperRow()) + i2 = 0; + if (i1 != 0) + Face1 = TopoDS::Face(myFaces->Value(i1, jj)); + if (i2 != 0) + Face2 = TopoDS::Face(myFaces->Value(i2, jj)); + CorrectSameParameter(anEdge, Face1, Face2); + } + } + for (ii = 1; ii <= NbLaw; ii++) for (jj = 1; jj <= NbPath; jj++) { @@ -3083,7 +3262,7 @@ TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const } } - BRepFill_TrimShellCorner aTrim(aFaces, AxeOfBisPlane, aPlaneF); + BRepFill_TrimShellCorner aTrim(aFaces, Transition, AxeOfBisPlane); aTrim.AddBounds(Bounds); aTrim.AddUEdges(aUEdges); aTrim.Perform(); @@ -3172,7 +3351,8 @@ TopoDS_Shape BRepFill_Sweep::Tape(const Standard_Integer Index) const // Filling B = Filling(It1.Value(), myFaces->Value(ii, I1), It2.Value(), myFaces->Value(ii, I2), - myVEdgesModified, myTol3d, Axe, T1, Bord1, Bord2, FF); + myVEdgesModified, myTol3d, Axe, T1, + Bord1, Bord2, FF); if (B) { myAuxShape.Append(FF); diff --git a/src/BRepFill/BRepFill_Sweep.hxx b/src/BRepFill/BRepFill_Sweep.hxx index b3b003a3f9..72b1897959 100644 --- a/src/BRepFill/BRepFill_Sweep.hxx +++ b/src/BRepFill/BRepFill_Sweep.hxx @@ -80,7 +80,7 @@ public: //! to be C0. Standard_EXPORT void SetForceApproxC1 (const Standard_Boolean ForceApproxC1); - //! Build the Sweeep Surface + //! Build the Sweep Surface //! Transition define Transition strategy //! Approx define Approximation Strategy //! - GeomFill_Section : The composed Function Location X Section @@ -118,13 +118,6 @@ public: protected: - - - - -private: - - Standard_EXPORT Standard_Boolean CorrectApproxParameters(); Standard_EXPORT Standard_Boolean BuildWire (const BRepFill_TransitionStyle Transition); @@ -142,6 +135,13 @@ private: Standard_EXPORT void RebuildTopOrBottomEdge (const TopoDS_Edge& aNewEdge, TopoDS_Edge& anEdge, TopTools_MapOfShape& ReversedEdges) const; + + +private: + + + + Standard_Boolean isDone; Standard_Boolean KPart; Standard_Real myTol3d; @@ -168,7 +168,6 @@ private: TopoDS_Wire FirstShape; TopoDS_Wire LastShape; - }; diff --git a/src/BRepFill/BRepFill_TrimShellCorner.cxx b/src/BRepFill/BRepFill_TrimShellCorner.cxx index 9d3e925ca6..0083bf8e23 100644 --- a/src/BRepFill/BRepFill_TrimShellCorner.cxx +++ b/src/BRepFill/BRepFill_TrimShellCorner.cxx @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,23 @@ #include #include #include +#include + +static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex, + TopoDS_Compound& theComp, + const gp_Ax1& theAxis); + +static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1, + const TopoDS_Vertex& theVertex2, + const gp_Ax1& theAxis, + TopoDS_Compound& theComp, + TopTools_ListOfShape& theElist); + +static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge, + const TopoDS_Edge& theLastEdge, + const TopoDS_Vertex& theFirstVertex, + const TopoDS_Vertex& theLastVertex, + TopoDS_Vertex& theCommonVertex); static Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS, const Standard_Integer theEIndex1, @@ -71,24 +89,6 @@ static Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS, Standard_Real& theParamOnE1, Standard_Real& theParamOnE2); -static Standard_Boolean MakeFacesNonSec(const Standard_Integer theIndex, - const Handle(TopTools_HArray2OfShape)& theUEdges, - const Handle(TopTools_HArray2OfShape)& theBounds, - const BOPDS_PDS& theDS, - const Standard_Integer theFaceIndex1, - const Standard_Integer theFaceIndex2, - TopTools_DataMapOfShapeListOfShape& theHistMap); - -static Standard_Boolean MakeFacesSec(const Standard_Integer theIndex, - const Handle(TopTools_HArray2OfShape)& theUEdges, - const Handle(TopTools_HArray2OfShape)& theBounds, - const BOPDS_PDS& theDS, - const Standard_Integer theFaceIndex1, - const Standard_Integer theFaceIndex2, - const Standard_Integer theSSInterfIndex, - const gp_Ax2& AxeOfBisPlane, - TopTools_DataMapOfShapeListOfShape& theHistMap); - static Standard_Boolean SplitUEdges(const Handle(TopTools_HArray2OfShape)& theUEdges, const BOPDS_PDS& theDS, TopTools_DataMapOfShapeListOfShape& theHistMap); @@ -186,55 +186,27 @@ static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWir gp_Pln& thePlane, Standard_Boolean& IsSingular); -static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp, - const gp_Ax2& bis, - TopoDS_Shape& resWire, - gp_Pln& resPlane, - Standard_Boolean& IsSingular); - -// =========================================================================================== -// function: Constructor -// purpose: -// =========================================================================================== -BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, - const gp_Ax2& theAxeOfBisPlane, - const TopoDS_Face& theSecPlane) : -myAxeOfBisPlane(theAxeOfBisPlane), -myDone(Standard_False), -myHasSection(Standard_False) -{ - myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(), - theFaces->LowerCol(), theFaces->UpperCol()); - myFaces->ChangeArray2() = theFaces->Array2(); - mySecPln = theSecPlane; -} +static void UpdateSectionEdge(TopoDS_Edge& theEdge, + const TopoDS_Vertex& theConstVertex, + TopoDS_Vertex& theVertex, + const Standard_Real theParam); + // =========================================================================================== // function: Constructor // purpose: // =========================================================================================== BRepFill_TrimShellCorner::BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, - const gp_Ax2& theAxeOfBisPlane, - const TopoDS_Wire& theSpine, - const TopoDS_Face& theSecPlane): -myAxeOfBisPlane(theAxeOfBisPlane), -myDone(Standard_False), -myHasSection(Standard_False) + const BRepFill_TransitionStyle theTransition, + const gp_Ax2& theAxeOfBisPlane) : + myTransition(theTransition), + myAxeOfBisPlane(theAxeOfBisPlane), + myDone(Standard_False), + myHasSection(Standard_False) { myFaces = new TopTools_HArray2OfShape(theFaces->LowerRow(), theFaces->UpperRow(), theFaces->LowerCol(), theFaces->UpperCol()); myFaces->ChangeArray2() = theFaces->Array2(); - mySpine = theSpine; - mySecPln = theSecPlane; -} - -// =========================================================================================== -// function: SetSpine -// purpose: -// =========================================================================================== -void BRepFill_TrimShellCorner::SetSpine(const TopoDS_Wire& theSpine) -{ - mySpine = theSpine; } // =========================================================================================== @@ -351,14 +323,13 @@ void BRepFill_TrimShellCorner::Perform() } if(!bhassec) { - if(!MakeFacesNonSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, myHistMap)) { + if(!MakeFacesNonSec(ii, theDS, anIndex1, anIndex2)) { myHistMap.Clear(); return; } } else { - if(!MakeFacesSec(ii, myUEdges, myBounds, theDS, anIndex1, anIndex2, - i, myAxeOfBisPlane, myHistMap)) { + if(!MakeFacesSec(ii, theDS, anIndex1, anIndex2, i)) { myHistMap.Clear(); return; } @@ -403,23 +374,21 @@ void BRepFill_TrimShellCorner::Modified(const TopoDS_Shape& theShape, } // ---------------------------------------------------------------------------------------------------- -// static function: MakeFacesNonSec -// purpose: +// function: MakeFacesNonSec +// purpose: Updates by new faces in the case when old faces do not intersect // ---------------------------------------------------------------------------------------------------- -Standard_Boolean MakeFacesNonSec(const Standard_Integer theIndex, - const Handle(TopTools_HArray2OfShape)& theUEdges, - const Handle(TopTools_HArray2OfShape)& theBounds, - const BOPDS_PDS& theDS, - const Standard_Integer theFaceIndex1, - const Standard_Integer theFaceIndex2, - TopTools_DataMapOfShapeListOfShape& theHistMap) +Standard_Boolean +BRepFill_TrimShellCorner::MakeFacesNonSec(const Standard_Integer theIndex, + const BOPDS_PDS& theDS, + const Standard_Integer theFaceIndex1, + const Standard_Integer theFaceIndex2) { Standard_Boolean bHasNewEdge = Standard_False; TopoDS_Edge aNewEdge; BRep_Builder aBB; - const TopoDS_Shape& aE1 = theBounds->Value(theIndex, 1); - const TopoDS_Shape& aE2 = theBounds->Value(theIndex, 2); + const TopoDS_Shape& aE1 = myBounds->Value(theIndex, 1); + const TopoDS_Shape& aE2 = myBounds->Value(theIndex, 2); // search common vertex between bounds. begin TopoDS_Vertex aCommonVertex; @@ -439,20 +408,20 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI Standard_Integer ueit = 0, eindex = 0; for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) { - const TopoDS_Shape& aShape1 = theUEdges->Value(eindex, theUEdges->LowerCol()); - const TopoDS_Shape& aShape2 = theUEdges->Value(eindex, theUEdges->UpperCol()); + const TopoDS_Shape& aShape1 = myUEdges->Value(eindex, myUEdges->LowerCol()); + const TopoDS_Shape& aShape2 = myUEdges->Value(eindex, myUEdges->UpperCol()); TopoDS_Edge aUE1 = TopoDS::Edge(aShape1); TopoDS_Edge aUE2 = TopoDS::Edge(aShape2); - if(theHistMap.IsBound(aShape1)) { - const TopTools_ListOfShape& lst = theHistMap.Find(aShape1); + if (myHistMap.IsBound(aShape1)) { + const TopTools_ListOfShape& lst = myHistMap.Find(aShape1); if(!lst.IsEmpty()) aUE1 = TopoDS::Edge(lst.First()); } - if(theHistMap.IsBound(aShape2)) { - const TopTools_ListOfShape& lst = theHistMap.Find(aShape2); + if (myHistMap.IsBound(aShape2)) { + const TopTools_ListOfShape& lst = myHistMap.Find(aShape2); if(!lst.IsEmpty()) aUE2 = TopoDS::Edge(lst.First()); @@ -499,11 +468,11 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI aBB.MakeCompound(aComp); for(ueit = 1, eindex = theIndex; ueit <= 2; ueit++, eindex++) { - const TopoDS_Shape& aShape = theUEdges->Value(eindex, theUEdges->LowerCol() + fit - 1); + const TopoDS_Shape& aShape = myUEdges->Value(eindex, myUEdges->LowerCol() + fit - 1); TopoDS_Shape aUE = aShape; - if(theHistMap.IsBound(aShape)) { - const TopTools_ListOfShape& lst = theHistMap.Find(aShape); + if(myHistMap.IsBound(aShape)) { + const TopTools_ListOfShape& lst = myHistMap.Find(aShape); if(!lst.IsEmpty()) aUE = TopoDS::Edge(lst.First()); @@ -638,7 +607,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI aNewFace.Orientation(aFaceOri); TopTools_ListOfShape atmpList; atmpList.Append(aNewFace); - theHistMap.Bind(aFace, atmpList); + myHistMap.Bind(aFace, atmpList); anExpE.Init(aFace, TopAbs_EDGE); @@ -648,7 +617,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current())) continue; - if(theHistMap.IsBound(anExpE.Current())) + if (myHistMap.IsBound(anExpE.Current())) continue; TopTools_ListOfShape aListOfNewEdge; TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE); @@ -656,7 +625,7 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI for(; anExpE2.More(); anExpE2.Next()) { aListOfNewEdge.Append(anExpE2.Current()); } - theHistMap.Bind(anExpE.Current(), aListOfNewEdge); + myHistMap.Bind(anExpE.Current(), aListOfNewEdge); } } @@ -664,18 +633,15 @@ Standard_Boolean MakeFacesNonSec(const Standard_Integer theI } // ---------------------------------------------------------------------------------------------------- -// static function: MakeFacesSec -// purpose: +// function: MakeFacesSec +// purpose: Updates by new faces in the case when old faces intersect each other // ---------------------------------------------------------------------------------------------------- -Standard_Boolean MakeFacesSec(const Standard_Integer theIndex, - const Handle(TopTools_HArray2OfShape)& theUEdges, - const Handle(TopTools_HArray2OfShape)& theBounds, - const BOPDS_PDS& theDS, - const Standard_Integer theFaceIndex1, - const Standard_Integer theFaceIndex2, - const Standard_Integer theSSInterfIndex, - const gp_Ax2& AxeOfBisPlane, - TopTools_DataMapOfShapeListOfShape& theHistMap) +Standard_Boolean +BRepFill_TrimShellCorner::MakeFacesSec(const Standard_Integer theIndex, + const BOPDS_PDS& theDS, + const Standard_Integer theFaceIndex1, + const Standard_Integer theFaceIndex2, + const Standard_Integer theSSInterfIndex) { const BOPDS_VectorOfInterfFF& aFFs = theDS->InterfFF(); const BOPDS_InterfFF& aFFi = aFFs(theSSInterfIndex); @@ -687,10 +653,30 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde if(!FilterSectionEdges(aBCurves, aSecPlane, theDS, aSecEdges)) return Standard_False; + //Extract vertices on the intersection of correspondent U-edges + const TopoDS_Shape& LeftE1 = myUEdges->Value(theIndex, 1); + const TopoDS_Shape& LeftE2 = myUEdges->Value(theIndex, 2); + const TopoDS_Shape& RightE1 = myUEdges->Value(theIndex+1, 1); + const TopoDS_Shape& RightE2 = myUEdges->Value(theIndex+1, 2); + + Standard_Integer IndexOfLeftE1 = theDS->Index(LeftE1); + Standard_Integer IndexOfLeftE2 = theDS->Index(LeftE2); + Standard_Integer IndexOfRightE1 = theDS->Index(RightE1); + Standard_Integer IndexOfRightE2 = theDS->Index(RightE2); + + TopoDS_Vertex FirstVertex, LastVertex; + Standard_Real ParamOnLeftE1, ParamOnLeftE2, ParamOnRightE1, ParamOnRightE2; + FindCommonVertex(theDS, IndexOfLeftE1, IndexOfLeftE2, + FirstVertex, ParamOnLeftE1, ParamOnLeftE2); + FindCommonVertex(theDS, IndexOfRightE1, IndexOfRightE2, + LastVertex, ParamOnRightE1, ParamOnRightE2); + TopoDS_Shape SecWire; gp_Pln SecPlane; Standard_Boolean IsSingular; - Standard_Boolean WireFound = ChooseSection( aSecEdges, AxeOfBisPlane, SecWire, SecPlane, IsSingular ); + Standard_Boolean WireFound = ChooseSection(aSecEdges, + FirstVertex, LastVertex, + SecWire, SecPlane, IsSingular ); if(WireFound) { //aSecEdges = SecWire; @@ -715,19 +701,19 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde TopAbs_Orientation aFaceOri = aFace.Orientation(); TopoDS_Face aFaceF = aFace; aFaceF.Orientation(TopAbs_FORWARD); - TopoDS_Edge aBoundEdge = TopoDS::Edge(theBounds->Value(theIndex, theBounds->LowerCol() +fit)); + TopoDS_Edge aBoundEdge = TopoDS::Edge(myBounds->Value(theIndex, myBounds->LowerCol() +fit)); Standard_Integer aBoundEdgeIndex = theDS->Index(aBoundEdge); TopoDS_Edge aUE1; TopoDS_Edge aUE2; - if(!GetUEdges(theIndex, fit, theUEdges, aBoundEdge, aFaceF, aUE1, aUE2)) + if(!GetUEdges(theIndex, fit, myUEdges, aBoundEdge, aFaceF, aUE1, aUE2)) return Standard_False; TopoDS_Edge aUE1old = aUE1; TopoDS_Edge aUE2old = aUE2; - if(theHistMap.IsBound(aUE1)) { - const TopTools_ListOfShape& lst = theHistMap.Find(aUE1); + if (myHistMap.IsBound(aUE1)) { + const TopTools_ListOfShape& lst = myHistMap.Find(aUE1); if(!lst.IsEmpty()) { const TopoDS_Shape& anEdge = lst.First().Oriented(aUE1.Orientation()); @@ -738,8 +724,8 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde } } - if(theHistMap.IsBound(aUE2)) { - const TopTools_ListOfShape& lst = theHistMap.Find(aUE2); + if (myHistMap.IsBound(aUE2)) { + const TopTools_ListOfShape& lst = myHistMap.Find(aUE2); if(!lst.IsEmpty()) { const TopoDS_Shape& anEdge = lst.First().Oriented(aUE2.Orientation()); @@ -757,12 +743,12 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde Standard_Boolean isPave1OnUEdge = Standard_True; if(FindFromUEdge(aUE1old, aUE2old, aUE1, aUE2, aFace, aSecEdges, fit, aBoundEdge, aBoundEdgeIndex, - theDS, theHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) { + theDS, myHistMap, aCompOfSecEdges, aListOfWireEdges, aPave1, isPave1OnUEdge)) { TopTools_ListOfShape aSecondListOfEdges; Standard_Boolean bisSectionFound = Standard_False; if(!FindFromVEdge(aPave1, isPave1OnUEdge, aUE1old, aUE2old, aFace, aCompOfSecEdges, fit, aBoundEdge, - aBoundEdgeIndex, theDS, theHistMap, aSecondListOfEdges, bisSectionFound)) { + aBoundEdgeIndex, theDS, myHistMap, aSecondListOfEdges, bisSectionFound)) { return Standard_False; } @@ -792,7 +778,7 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde aNewFace.Orientation(aFaceOri); TopTools_ListOfShape atmpList; atmpList.Append(aNewFace); - theHistMap.Bind(aFace, atmpList); + myHistMap.Bind(aFace, atmpList); TopExp_Explorer anExpE(aFace, TopAbs_EDGE); @@ -802,7 +788,7 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde if(aNewValue.IsNull() || aNewValue.IsSame(anExpE.Current())) continue; - if(theHistMap.IsBound(anExpE.Current())) + if (myHistMap.IsBound(anExpE.Current())) continue; TopTools_ListOfShape aListOfNewEdge; TopExp_Explorer anExpE2(aNewValue, TopAbs_EDGE); @@ -810,12 +796,240 @@ Standard_Boolean MakeFacesSec(const Standard_Integer theInde for(; anExpE2.More(); anExpE2.Next()) { aListOfNewEdge.Append(anExpE2.Current()); } - theHistMap.Bind(anExpE.Current(), aListOfNewEdge); + myHistMap.Bind(anExpE.Current(), aListOfNewEdge); } } return Standard_True; } +//======================================================================= +//function : ChooseSection +//purpose : +//======================================================================= +Standard_Boolean BRepFill_TrimShellCorner::ChooseSection(const TopoDS_Shape& Comp, + const TopoDS_Vertex& theFirstVertex, + const TopoDS_Vertex& theLastVertex, + TopoDS_Shape& resWire, + gp_Pln& resPlane, + Standard_Boolean& IsSingular) +{ + IsSingular = Standard_False; + + Standard_Integer ind, i, j; + BRep_Builder BB; + + if (myTransition == BRepFill_Right && + !theFirstVertex.IsNull() && + !theLastVertex.IsNull()) //the case where section wire goes from + //its known first vertex to its known last vertex + { + TopoDS_Wire NewWire; + BB.MakeWire(NewWire); + + TopoDS_Compound OldComp; + BB.MakeCompound( OldComp ); + TopoDS_Iterator iter( Comp ); + for (; iter.More(); iter.Next()) + BB.Add( OldComp, iter.Value() ); + + TopoDS_Edge FirstEdge = FindEdgeCloseToBisectorPlane(theFirstVertex, + OldComp, + myAxeOfBisPlane.Axis()); + iter.Initialize(OldComp); + if (!iter.More()) + { + iter.Initialize(Comp); + BB.Add( OldComp, iter.Value() ); + } + TopoDS_Edge LastEdge = FindEdgeCloseToBisectorPlane(theLastVertex, + OldComp, + myAxeOfBisPlane.Axis()); + + BB.Add(NewWire, FirstEdge); + + if (!FirstEdge.IsSame(LastEdge)) + { + TopoDS_Vertex aCommonVertex; + Standard_Boolean CommonVertexExists = FindCommonVertex(FirstEdge, LastEdge, + theFirstVertex, theLastVertex, + aCommonVertex); + if (CommonVertexExists) + BB.Add(NewWire, LastEdge); + else + { + TopoDS_Vertex Vertex1, Vertex2, V1, V2; + TopExp::Vertices(FirstEdge, V1, V2); + Vertex1 = (theFirstVertex.IsSame(V1))? V2 : V1; + TopExp::Vertices(LastEdge, V1, V2); + Vertex2 = (theLastVertex.IsSame(V1))? V2 : V1; + + TopTools_ListOfShape MiddleEdges; + if (FindMiddleEdges(Vertex1, Vertex2, myAxeOfBisPlane.Axis(), OldComp, MiddleEdges)) + { + TopTools_ListIteratorOfListOfShape itl(MiddleEdges); + for (; itl.More(); itl.Next()) + BB.Add(NewWire, itl.Value()); + BB.Add(NewWire, LastEdge); + } + else + { + //trim and in the points of extrema + //these points become new vertex with centre between them + BRepExtrema_ExtCC Extrema(FirstEdge, LastEdge); + if (Extrema.IsDone() && Extrema.NbExt() > 0) + { + Standard_Integer imin = 1; + for (i = 2; i <= Extrema.NbExt(); i++) + if (Extrema.SquareDistance(i) < Extrema.SquareDistance(imin)) + imin = i; + + Standard_Real aMinDist = sqrt(Extrema.SquareDistance(imin)); + Standard_Real ParamOnFirstEdge = Extrema.ParameterOnE1(imin); + Standard_Real ParamOnLastEdge = Extrema.ParameterOnE2(imin); + gp_Pnt PointOnFirstEdge = Extrema.PointOnE1(imin); + gp_Pnt PointOnLastEdge = Extrema.PointOnE2(imin); + gp_Pnt MidPnt((PointOnFirstEdge.XYZ() + PointOnLastEdge.XYZ())/2); + aCommonVertex = BRepLib_MakeVertex(MidPnt); + BB.UpdateVertex(aCommonVertex, 1.001*aMinDist/2); + + UpdateSectionEdge(FirstEdge, theFirstVertex, aCommonVertex, ParamOnFirstEdge); + UpdateSectionEdge(LastEdge, theLastVertex, aCommonVertex, ParamOnLastEdge); + + BB.Add(NewWire, LastEdge); + } + } + } + } + + resWire = NewWire; + resPlane = gp_Pln(myAxeOfBisPlane); + return Standard_True; + } + + //General case: try to find continuous section closest to bisector plane + TopoDS_Compound OldComp; + BRep_Builder B; + B.MakeCompound( OldComp ); + TopoDS_Iterator iter( Comp ); + for (; iter.More(); iter.Next()) + B.Add( OldComp, iter.Value() ); + + Standard_Boolean anError = Standard_False; + //TopoDS_Wire NewWire [2]; + TopTools_SequenceOfShape Wseq; + for (;;) + { + TopExp_Explorer explo( OldComp, TopAbs_EDGE ); + if (!explo.More()) + break; + TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() ); + TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge ); + B.Remove( OldComp, FirstEdge ); + if (NewWire.Closed()) + { + Wseq.Append(NewWire); + continue; + } + + for (;;) + { + TopoDS_Vertex Extremity [2]; + TopExp::Vertices( NewWire, Extremity[0], Extremity[1] ); + if (Extremity[0].IsNull() || Extremity[1].IsNull()) + { + anError = Standard_True; + break; + } + TopTools_IndexedDataMapOfShapeListOfShape VEmap; + TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap ); + TopTools_ListOfShape Vedges [2]; + for (j = 0; j < 2; j++) + if (VEmap.Contains( Extremity[j] )) + Vedges[j] = VEmap.FindFromKey( Extremity[j] ); + if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty()) + //no more edges in OldComp to continue NewWire + break; + Standard_Boolean Modified = Standard_False; + for (j = 0; j < 2; j++) + { + if (Vedges[j].Extent() == 1) + { + const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() ); + NewWire = BRepLib_MakeWire( NewWire, anEdge ); + B.Remove( OldComp, anEdge ); + Modified = Standard_True; + } + } + if (!Modified) //only multiple connections + { + ind = (Vedges[0].IsEmpty())? 1 : 0; + TopTools_SequenceOfShape Edges; + TopTools_ListIteratorOfListOfShape itl( Vedges[ind] ); + for (; itl.More(); itl.Next()) + Edges.Append( itl.Value() ); + Standard_Integer theind=0; + Standard_Real MinDeviation = RealLast(); + for (j = 1; j <= Edges.Length(); j++) + { + TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) ); + gp_Pln aPlane; + Standard_Boolean issing; + Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing ); + if (Deviation < MinDeviation) + { + MinDeviation = Deviation; + theind = j; + } + } + NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) ); + B.Remove( OldComp, Edges(theind) ); + } + if (NewWire.Closed()) + break; + } + Wseq.Append(NewWire); + if (anError) + break; + } + + Standard_Real MinAngle = RealLast(); + TopExp_Explorer Explo( OldComp, TopAbs_EDGE ); + if (!anError && !Explo.More()) //wires are built successfully and compound is empty + { + if (Wseq.Length() == 1) //only one wire => it becomes result + { + resWire = Wseq.First(); + ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular ); + return Standard_True; + } + else //we must choose the wire which average plane is closest to bisector plane + { //(check angle between axes) + for (i = 1; i <= Wseq.Length(); i++) + { + TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) ); + gp_Pln aPln; + Standard_Boolean issing; + ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing ); + if (issing) + continue; + + Standard_Real Angle = aPln.Axis().Angle( myAxeOfBisPlane.Axis() ); + if (Angle > M_PI/2) + Angle = M_PI - Angle; + + if (Angle < MinAngle) + { + MinAngle = Angle; + resWire = aWire; + resPlane = aPln; + } + } + return Standard_True; + } + } + return Standard_False; +} + // ------------------------------------------------------------------------------------------ // static function: SplitUEdges @@ -966,13 +1180,15 @@ Standard_Boolean FindCommonVertex(const BOPDS_PDS& theDS, continue; IntTools_CommonPrt aCP = aEE.CommonPart(); - if(aCP.Type() == TopAbs_VERTEX) { + if(aCP.Type() == TopAbs_VERTEX) + { theCommonVertex = *(TopoDS_Vertex*)&theDS->Shape(aEE.IndexNew()); - if (theEIndex1 == aEE.Index1()) { + + if (theEIndex1 == aEE.Index1()) IntTools_Tools::VertexParameters(aCP, theParamOnE1, theParamOnE2); - } else { + else IntTools_Tools::VertexParameters(aCP, theParamOnE2, theParamOnE1); - } + // bvertexfound = Standard_True; break; @@ -2004,147 +2220,182 @@ static Standard_Real ComputeAveragePlaneAndMaxDeviation(const TopoDS_Shape& aWir return MaxDeviation; } -//======================================================================= -//function : ChooseSection -//purpose : -//======================================================================= -static Standard_Boolean ChooseSection(const TopoDS_Shape& Comp, - const gp_Ax2& bis, - TopoDS_Shape& resWire, - gp_Pln& resPlane, - Standard_Boolean& IsSingular) + +static void UpdateSectionEdge(TopoDS_Edge& theEdge, + const TopoDS_Vertex& theConstVertex, + TopoDS_Vertex& theVertex, + const Standard_Real theParam) { - IsSingular = Standard_False; - Standard_Real TolDeviation = 0.01; //, TolConf = 1.e-4, TolAng = 1.e-5; + TopoDS_Edge F_Edge = theEdge; + F_Edge.Orientation(TopAbs_FORWARD); + + TopAbs_Orientation OrOfVertex; + TopoDS_Vertex V1, V2, AnotherVertex; + TopExp::Vertices(F_Edge, V1, V2); + if (theConstVertex.IsSame(V1)) + { + //OrOfConst = TopAbs_FORWARD; + OrOfVertex = TopAbs_REVERSED; + AnotherVertex = V2; + } + else + { + //OrOfConst = TopAbs_REVERSED; + OrOfVertex = TopAbs_FORWARD; + AnotherVertex = V1; + } -// Standard_Integer N = 100; - Standard_Integer ind, i, j; + BRep_Builder BB; + Standard_Real fpar, lpar; + BRep_Tool::Range(F_Edge, fpar, lpar); + if (OrOfVertex == TopAbs_FORWARD) + fpar = theParam; + else + lpar = theParam; + BB.Range(F_Edge, fpar, lpar); + + F_Edge.Free(Standard_True); + BB.Remove(F_Edge, AnotherVertex); + theVertex.Orientation(OrOfVertex); + BB.Add(F_Edge, theVertex); +} - //Simplest case - TopoDS_Compound OldComp; - BRep_Builder B; - B.MakeCompound( OldComp ); - TopoDS_Iterator iter( Comp ); - for (; iter.More(); iter.Next()) - B.Add( OldComp, iter.Value() ); +//Finds the edge connected to in the compound +//that is closest to bisector plane angularly. +//Removes found edge from +// is the axis of bisector plane +static TopoDS_Edge FindEdgeCloseToBisectorPlane(const TopoDS_Vertex& theVertex, + TopoDS_Compound& theComp, + const gp_Ax1& theAxis) +{ + TopTools_IndexedDataMapOfShapeListOfShape VEmap; + TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap ); + + TopoDS_Edge MinEdge; + if (!VEmap.Contains(theVertex)) + return MinEdge; + + BRep_Builder BB; + + const TopTools_ListOfShape& Edges = VEmap.FindFromKey(theVertex); + if (Edges.Extent() == 1) + MinEdge = TopoDS::Edge(Edges.First()); + else + { + TopTools_ListIteratorOfListOfShape itl(Edges); + Standard_Real MinAngle = RealLast(); + for (; itl.More(); itl.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge(itl.Value()); + TopoDS_Wire aWire; + BB.MakeWire(aWire); + BB.Add(aWire, anEdge); + gp_Pln aPln; + Standard_Boolean issing; + ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing ); + Standard_Real anAngle; + if (issing) //edge is a segment of line + { + // is angle between and its projection on bisector plane + BRepAdaptor_Curve BAcurve(anEdge); + gp_Pnt FirstPnt = BAcurve.Value(BAcurve.FirstParameter()); + gp_Pnt LastPnt = BAcurve.Value(BAcurve.LastParameter()); + gp_Vec EdgeVec(FirstPnt, LastPnt); + gp_Ax1 EdgeAxis(FirstPnt, EdgeVec); + anAngle = EdgeAxis.Direction().Angle(theAxis.Direction()); + if (anAngle > M_PI/2) + anAngle = M_PI - anAngle; + anAngle = M_PI/2 - anAngle; + } + else + { + anAngle = aPln.Axis().Angle( theAxis ); + if (anAngle > M_PI/2) + anAngle = M_PI - anAngle; + } + + if (anAngle < MinAngle) + { + MinAngle = anAngle; + MinEdge = anEdge; + } + } + } //else (more than one edge) - Standard_Boolean anError = Standard_False; - //TopoDS_Wire NewWire [2]; - TopTools_SequenceOfShape Wseq; + BB.Remove(theComp, MinEdge); + return MinEdge; +} + +static Standard_Boolean FindMiddleEdges(const TopoDS_Vertex& theVertex1, + const TopoDS_Vertex& theVertex2, + const gp_Ax1& theAxis, + TopoDS_Compound& theComp, + TopTools_ListOfShape& theElist) +{ + TopTools_IndexedDataMapOfShapeListOfShape VEmap; + TopExp::MapShapesAndAncestors( theComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap ); + if (VEmap.IsEmpty()) + return Standard_False; + + if (!VEmap.Contains(theVertex1) || + !VEmap.Contains(theVertex2)) + return Standard_False; + + TopoDS_Vertex CurVertex = theVertex1; for (;;) - { - TopExp_Explorer explo( OldComp, TopAbs_EDGE ); - if (!explo.More()) - break; - TopoDS_Edge FirstEdge = TopoDS::Edge( explo.Current() ); - TopoDS_Wire NewWire = BRepLib_MakeWire( FirstEdge ); - B.Remove( OldComp, FirstEdge ); - if (NewWire.Closed()) - { - Wseq.Append(NewWire); - continue; - } + { + TopoDS_Edge CurEdge; + + CurEdge = FindEdgeCloseToBisectorPlane(CurVertex, theComp, theAxis); + if (CurEdge.IsNull()) + return Standard_False; + + TopoDS_Vertex V1, V2; + TopExp::Vertices(CurEdge, V1, V2); + CurVertex = (V1.IsSame(CurVertex))? V2 : V1; - for (;;) - { - TopoDS_Vertex Extremity [2]; - TopExp::Vertices( NewWire, Extremity[0], Extremity[1] ); - if (Extremity[0].IsNull() || Extremity[1].IsNull()) - { - anError = Standard_True; - break; - } - TopTools_IndexedDataMapOfShapeListOfShape VEmap; - TopExp::MapShapesAndAncestors( OldComp, TopAbs_VERTEX, TopAbs_EDGE, VEmap ); - TopTools_ListOfShape Vedges [2]; - for (j = 0; j < 2; j++) - if (VEmap.Contains( Extremity[j] )) - Vedges[j] = VEmap.FindFromKey( Extremity[j] ); - if (Vedges[0].IsEmpty() && Vedges[1].IsEmpty()) - //no more edges in OldComp to continue NewWire - break; - Standard_Boolean Modified = Standard_False; - for (j = 0; j < 2; j++) - { - if (Vedges[j].Extent() == 1) - { - const TopoDS_Edge& anEdge = TopoDS::Edge( Vedges[j].First() ); - NewWire = BRepLib_MakeWire( NewWire, anEdge ); - B.Remove( OldComp, anEdge ); - Modified = Standard_True; - } - } - if (!Modified) //only multiple connections - { - ind = (Vedges[0].IsEmpty())? 1 : 0; - TopTools_SequenceOfShape Edges; - TopTools_ListIteratorOfListOfShape itl( Vedges[ind] ); - for (; itl.More(); itl.Next()) - Edges.Append( itl.Value() ); - Standard_Integer theind=0; - Standard_Real MinDeviation = RealLast(); - for (j = 1; j <= Edges.Length(); j++) - { - TopoDS_Wire aWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(j)) ); - gp_Pln aPlane; - Standard_Boolean issing; - Standard_Real Deviation = ComputeAveragePlaneAndMaxDeviation( aWire, aPlane, issing ); - if (Deviation < MinDeviation) - { - MinDeviation = Deviation; - theind = j; - } - } - NewWire = BRepLib_MakeWire( NewWire, TopoDS::Edge(Edges(theind)) ); - B.Remove( OldComp, Edges(theind) ); - } - if (NewWire.Closed()) - break; - } - Wseq.Append(NewWire); - if (anError) - break; - } + theElist.Append(CurEdge); + if (CurVertex.IsSame(theVertex2)) + return Standard_True; + } +} - Standard_Real Deviation=0.; - Standard_Real MinAngle = RealLast(); - TopExp_Explorer Explo( OldComp, TopAbs_EDGE ); - if (!anError && !Explo.More()) +static Standard_Boolean FindCommonVertex(const TopoDS_Edge& theFirstEdge, + const TopoDS_Edge& theLastEdge, + const TopoDS_Vertex& theFirstVertex, + const TopoDS_Vertex& theLastVertex, + TopoDS_Vertex& theCommonVertex) +{ + if (!theFirstVertex.IsSame(theLastVertex)) + { + Standard_Boolean CommonVertexExists = TopExp::CommonVertex(theFirstEdge, + theLastEdge, + theCommonVertex); + return CommonVertexExists; + } + + TopoDS_Vertex V1, V2, V3, V4; + TopExp::Vertices(theFirstEdge, V1, V2); + TopExp::Vertices(theLastEdge, V3, V4); + + if (V1.IsSame(theFirstVertex)) + { + if (V2.IsSame(V3) || + V2.IsSame(V4)) { - if (Wseq.Length() == 1) - { - resWire = Wseq.First(); - Deviation = ComputeAveragePlaneAndMaxDeviation( resWire, resPlane, IsSingular ); - return Standard_True; - } - else - { - for (i = 1; i <= Wseq.Length(); i++) - { - TopoDS_Wire aWire = TopoDS::Wire( Wseq(i) ); - gp_Pln aPln; - Standard_Boolean issing; - Standard_Real aDeviation = - ComputeAveragePlaneAndMaxDeviation( aWire, aPln, issing ); - if (issing) - continue; - - Standard_Real Angle = aPln.Axis().Angle( bis.Axis() ); - if (Angle > M_PI/2) - Angle = M_PI - Angle; - - if (Angle < MinAngle) - { - MinAngle = Angle; - resWire = aWire; - resPlane = aPln; - Deviation = aDeviation; - } - } - if (Deviation <= TolDeviation) - return Standard_True; - } + theCommonVertex = V2; + return Standard_True; } + } + else + { + if (V1.IsSame(V3) || + V1.IsSame(V4)) + { + theCommonVertex = V1; + return Standard_True; + } + } + return Standard_False; - //end of simplest case } diff --git a/src/BRepFill/BRepFill_TrimShellCorner.hxx b/src/BRepFill/BRepFill_TrimShellCorner.hxx index 2298d7c6b4..a134916e8b 100644 --- a/src/BRepFill/BRepFill_TrimShellCorner.hxx +++ b/src/BRepFill/BRepFill_TrimShellCorner.hxx @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -28,13 +29,14 @@ #include #include #include +#include class gp_Ax2; class TopoDS_Face; class TopoDS_Wire; class TopoDS_Shape; - +//! Trims sets of faces in the corner to make proper parts of pipe class BRepFill_TrimShellCorner { public: @@ -42,12 +44,13 @@ public: DEFINE_STANDARD_ALLOC - Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, const gp_Ax2& theAxeOfBisPlane, const TopoDS_Face& theSecPlane); - - Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, const gp_Ax2& theAxeOfBisPlane, const TopoDS_Wire& theSpine, const TopoDS_Face& theSecPlane); - - Standard_EXPORT void SetSpine (const TopoDS_Wire& theSpine); - + //! Constructor: takes faces to intersect, + //! type of transition (it can be RightCorner or RoundCorner) + //! and axis of bisector plane + Standard_EXPORT BRepFill_TrimShellCorner(const Handle(TopTools_HArray2OfShape)& theFaces, + const BRepFill_TransitionStyle theTransition, + const gp_Ax2& theAxeOfBisPlane); + Standard_EXPORT void AddBounds (const Handle(TopTools_HArray2OfShape)& Bounds); Standard_EXPORT void AddUEdges (const Handle(TopTools_HArray2OfShape)& theUEdges); @@ -71,13 +74,29 @@ protected: private: + Standard_Boolean MakeFacesSec(const Standard_Integer theIndex, + const BOPDS_PDS& theDS, + const Standard_Integer theFaceIndex1, + const Standard_Integer theFaceIndex2, + const Standard_Integer theSSInterfIndex); + + Standard_Boolean MakeFacesNonSec(const Standard_Integer theIndex, + const BOPDS_PDS& theDS, + const Standard_Integer theFaceIndex1, + const Standard_Integer theFaceIndex2); + + Standard_Boolean ChooseSection(const TopoDS_Shape& Comp, + const TopoDS_Vertex& theFirstVertex, + const TopoDS_Vertex& theLastVertex, + TopoDS_Shape& resWire, + gp_Pln& resPlane, + Standard_Boolean& IsSingular); + BRepFill_TransitionStyle myTransition; gp_Ax2 myAxeOfBisPlane; TopoDS_Shape myShape1; TopoDS_Shape myShape2; - TopoDS_Wire mySpine; - TopoDS_Face mySecPln; Handle(TopTools_HArray2OfShape) myBounds; Handle(TopTools_HArray2OfShape) myUEdges; Handle(TopTools_HArray2OfShape) myFaces; diff --git a/src/BRepFill/BRepFill_Voluved.cxx b/src/BRepFill/BRepFill_Voluved.cxx new file mode 100644 index 0000000000..9412050da3 --- /dev/null +++ b/src/BRepFill/BRepFill_Voluved.cxx @@ -0,0 +1,1794 @@ +// Created on: 2018-03-14 +// Created by: Nikolai BUKHALOV +// Copyright (c) 1999-2018 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + + +#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 + +static const Standard_Real aPipeLinearTolerance = 1.0e-4; +static const Standard_Real aPipeAngularTolerance = 1.0e-2; + +static const Standard_Boolean isParallelComputation = Standard_False; +const char aDirPatch[] = "T:\\pp\\"; + +static Standard_Boolean CheckSingularityAndAdd(const TopoDS_Face& theF, + const Standard_Real theFuzzyToler, + TopTools_ListOfShape& theListOfFaces, + TopTools_ListOfShape& theListOfSplits); + +//#define BREPFILL_VOLUVED_DEBUG + +//======================================================================= +//function : GetSpineAndProfile +//purpose : +//======================================================================= +void BRepFill_Voluved::GetSpineAndProfile(const TopoDS_Wire& theSpine, + const TopoDS_Wire& theProfile) +{ + mySpine = theSpine; + myProfile = theProfile; + + TopTools_IndexedDataMapOfShapeListOfShape aMVEP; + TopExp::MapShapesAndAncestors(theProfile, TopAbs_VERTEX, TopAbs_EDGE, aMVEP); + + gp_Vec aN2; + gp_Pnt aLoc; + + for (Standard_Integer i = 1; i <= aMVEP.Size(); i++) + { + const TopoDS_Vertex &aVC = TopoDS::Vertex(aMVEP.FindKey(i)); + + const TopTools_ListOfShape &aLE = aMVEP.FindFromIndex(i); + + if (aLE.Extent() < 2) + continue; + + const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First()); + const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last()); + + const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2); + + const Standard_Real aPar1 = BRep_Tool::Parameter(aVC, anE1); + const Standard_Real aPar2 = BRep_Tool::Parameter(aVC, anE2); + + gp_Pnt aP; + gp_Vec aT1, aT2; + + anAC1.D1(aPar1, aP, aT1); + anAC1.D1(aPar2, aP, aT2); + + aN2 = aT1.Crossed(aT2); + + if (aN2.SquareMagnitude() > Precision::SquareConfusion()) + { + aLoc = BRep_Tool::Pnt(aVC); + break; + } + } + + BRepExtrema_DistShapeShape anExtr; + anExtr.LoadS1(theSpine); + + if (aN2.SquareMagnitude() > Precision::SquareConfusion()) + { + const gp_Pln aPln(aLoc, aN2); + BRepLib_MakeFace aMF(aPln, theProfile); + if (!aMF.IsDone()) + return; + + anExtr.LoadS2(aMF.Face()); + } + else + { + anExtr.LoadS2(theProfile); + } + + if (!anExtr.Perform()) + return; + + const Standard_Integer aNbSol = anExtr.NbSolution(); + if (aNbSol < 1) + return; + + Standard_Real aDistMin = RealLast(); + Standard_Integer anIdxMin = 0; + + for (Standard_Integer aSolId = 1; aSolId <= aNbSol; aSolId++) + { + const Standard_Real aD = anExtr.Value(); + if (aD > aDistMin) + continue; + + aDistMin = aD; + anIdxMin = aSolId; + } + + BRepExtrema_SupportType anExtrType2 = anExtr.SupportTypeShape2(anIdxMin); + + if (aDistMin < Precision::Confusion()) + { + anExtrType2 = BRepExtrema_IsInFace; + } + + switch (anExtrType2) + { + case BRepExtrema_IsInFace: + if (anExtr.SupportTypeShape1(anIdxMin) == BRepExtrema_IsVertex) + { + const TopoDS_Vertex aV = TopoDS::Vertex(anExtr.SupportOnShape1(anIdxMin)); + TopTools_IndexedDataMapOfShapeListOfShape aMVES; + TopExp::MapShapesAndAncestors(theSpine, TopAbs_VERTEX, TopAbs_EDGE, aMVES); + + const TopTools_ListOfShape &aLE = aMVES.FindFromKey(aV); + + const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First()); + const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last()); + + const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2); + + const Standard_Real aPar1 = BRep_Tool::Parameter(aV, anE1); + const Standard_Real aPar2 = BRep_Tool::Parameter(aV, anE2); + + gp_Pnt aP; + gp_Vec aT1, aT2; + + anAC1.D1(aPar1, aP, aT1); + anAC1.D1(aPar2, aP, aT2); + + // Find minimal sine + const Standard_Real aSqT1 = Max(aT1.SquareMagnitude(), 1.0 / Precision::Infinite()); + const Standard_Real aSqT2 = Max(aT2.SquareMagnitude(), 1.0 / Precision::Infinite()); + + const Standard_Real aSqSin1 = aT1.CrossSquareMagnitude(aN2) / aSqT1; + const Standard_Real aSqSin2 = aT2.CrossSquareMagnitude(aN2) / aSqT2; + + if (aSqSin1 < aSqSin2) + { + if (aT1.Dot(aN2) > 0.0) + { + myProfile.Reverse(); + } + } + else + { + if (aT2.Dot(aN2) > 0.0) + { + myProfile.Reverse(); + } + } + } + else // if (... == BRepExtrema_IsOnEdge) + { + const TopoDS_Edge anE = TopoDS::Edge(anExtr.SupportOnShape1(anIdxMin)); + const BRepAdaptor_Curve anAC(anE); + Standard_Real aPar; + anExtr.ParOnEdgeS1(anIdxMin, aPar); + + gp_Pnt aP; + gp_Vec aT1; + anAC.D1(aPar, aP, aT1); + + if (aT1.Dot(aN2) > 0.0) + { + myProfile.Reverse(); + } + } + break; + + case BRepExtrema_IsOnEdge: + case BRepExtrema_IsVertex: + { + const BRepLib_MakeFace aMkFSpine(theSpine, Standard_True); + if (!aMkFSpine.IsDone()) + return; + + const TopoDS_Face &aFSpine = aMkFSpine.Face(); + const Handle(Geom_Plane) aPlnSpine = Handle(Geom_Plane)::DownCast(BRep_Tool::Surface(aFSpine)); + const gp_Vec aN1(aPlnSpine->Axis().Direction()); + gp_Vec aTanV; + + if (anExtr.SupportTypeShape2(anIdxMin) == BRepExtrema_IsVertex) + { + const TopoDS_Vertex aV = TopoDS::Vertex(anExtr.SupportOnShape2(anIdxMin)); + TopTools_IndexedDataMapOfShapeListOfShape aMVES; + TopExp::MapShapesAndAncestors(theProfile, TopAbs_VERTEX, TopAbs_EDGE, aMVES); + + const TopTools_ListOfShape &aLE = aMVES.FindFromKey(aV); + + const TopoDS_Edge &anE1 = TopoDS::Edge(aLE.First()); + const TopoDS_Edge &anE2 = TopoDS::Edge(aLE.Last()); + + const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2); + + const Standard_Real aPar1 = BRep_Tool::Parameter(aV, anE1); + const Standard_Real aPar2 = BRep_Tool::Parameter(aV, anE2); + + gp_Pnt aP; + gp_Vec aT1, aT2; + + anAC1.D1(aPar1, aP, aT1); + anAC1.D1(aPar2, aP, aT2); + + // Find maximal cosine + Standard_Real aSqT1 = aT1.SquareMagnitude(); + Standard_Real aSqT2 = aT2.SquareMagnitude(); + + if (aSqT1 < Precision::SquareConfusion()) + aSqT1 = RealLast(); + + if (aSqT2 < Precision::SquareConfusion()) + aSqT2 = RealLast(); + + const Standard_Real aDP1 = aT1.Dot(aN1); + const Standard_Real aDP2 = aT2.Dot(aN1); + + if (aDP1*aDP1*aSqT2 > aDP2*aDP2*aSqT1) + { + //aDP1*aDP1/aSqT1 > aDP2*aDP2/aSqT2 + aTanV = aT1; + } + else + { + aTanV = aT2; + } + } + else // if(anExtr.SupportTypeShape2(anIdxMin) == BRepExtrema_IsOnEdge) + { + const TopoDS_Edge anE = TopoDS::Edge(anExtr.SupportOnShape2(anIdxMin)); + const BRepAdaptor_Curve anAC(anE); + Standard_Real aPar; + anExtr.ParOnEdgeS2(anIdxMin, aPar); + + gp_Pnt aP; + anAC.D1(aPar, aP, aTanV); + } + + //The point in the profile, which is the nearest to the spine + const gp_Pnt &aPnear = anExtr.PointOnShape2(anIdxMin); + + BRepClass_FaceClassifier aFClass(aFSpine, aPnear, Precision::Confusion()); + if (aFClass.State() != TopAbs_OUT) + { + if (aN1.Dot(aTanV) < 0.0) + { + myProfile = TopoDS::Wire(theProfile.Reversed()); + } + } + else + { + if (aN1.Dot(aTanV) > 0.0) + { + myProfile = TopoDS::Wire(theProfile.Reversed()); + } + } + } + break; + default: + break; + } +} + +//======================================================================= +//function : Perform +//purpose : +//======================================================================= +void BRepFill_Voluved::Perform(const TopoDS_Wire& theSpine, + const TopoDS_Wire& theProfile, + const Standard_Real theTolerance, + const Standard_Boolean theSolidReq) +{ + myErrorStatus = BRepFill_Voluved_Empty; + + if (myFuzzyValue < Precision::Confusion()) + { + myFuzzyValue = theTolerance; + } + +#ifdef BREPFILL_VOLUVED_DEBUG + char aBuff[10000]; + Sprintf(aBuff, "%s%s", aDirPatch, "spine.nbv"); + BinTools::Write(theSpine, aBuff); + Sprintf(aBuff, "%s%s", aDirPatch, "profile.nbv"); + BinTools::Write(theProfile, aBuff); + + std::streamsize aPrecVal = std::cout.precision(); + + std::cout.precision(15); + + std::cout << "++++ Dump of Spine" << std::endl; + BRepTools::Dump(theSpine, std::cout); + std::cout << "---- Dump of Spine" << std::endl; + + std::cout << "++++ Dump of Profile" << std::endl; + BRepTools::Dump(theProfile, std::cout); + std::cout << "---- Dump of Profile" << std::endl; + + std::cout.precision(aPrecVal); +#endif + + GetSpineAndProfile(theSpine, theProfile); + + myPipeShell.Nullify(); + myTopBottom.Nullify(); + myResult.Nullify(); + +#ifdef BREPFILL_VOLUVED_DEBUG + std::cout << "Start Evolved. Toler = " << myFuzzyValue << std::endl; +#endif + + PerformSweep(); + +#ifdef BREPFILL_VOLUVED_DEBUG + std::cout << "PerformSweep complete. Status = " << myErrorStatus << std::endl; +#endif + + GetLids(); + +#ifdef BREPFILL_VOLUVED_DEBUG + std::cout << "GetLids complete. Status = " << myErrorStatus << std::endl; +#endif + + if ((myErrorStatus != BRepFill_Voluved_NotSolid) && !theSolidReq) + { + myResult = myPipeShell; + } + + BuildSolid(); +} + +//======================================================================= +//function : PerformSweep +//purpose : +//======================================================================= +void BRepFill_Voluved::PerformSweep() +{ + if (myErrorStatus != BRepFill_Voluved_Empty) + return; + + myErrorStatus = BRepFill_Voluved_SweepError; + + Handle(BRepFill_PipeShell) aPipe = new BRepFill_PipeShell(mySpine); + aPipe->SetTolerance(aPipeLinearTolerance, aPipeLinearTolerance, aPipeAngularTolerance); + aPipe->SetTransition(BRepFill_TransitionStyle::BRepFill_Round); + aPipe->Add(myProfile, Standard_False, Standard_False); + + if (aPipe->Build()) + { + myErrorStatus = BRepFill_Voluved_NoLids; + myPipeShell = aPipe->Shape(); + } +} + +//======================================================================= +//function : GetLids +//purpose : +//======================================================================= +void BRepFill_Voluved::GetLids() +{ + if (myPipeShell.IsNull()) + return; + + if (BRep_Tool::IsClosed(myProfile)) + { + // No need in lids creation + myErrorStatus = BRepFill_Voluved_NotSolid; + return; + } + + myErrorStatus = BRepFill_Voluved_NoLids; + + BRepLib_FindSurface aFS(mySpine, -1.0, Standard_True); + const Handle(Geom_Plane) aSurf = Handle(Geom_Plane)::DownCast(aFS.Surface()); + + if (aSurf.IsNull()) + { + myErrorStatus = BRepFill_Voluved_NotPlanarSpine; + return; + } + + //Square of the default angular tolerance in + //BOPAlgo_Tools::EdgesToWires(...) and BOPAlgo_Tools::WiresToFaces(...) methods + const Standard_Real aSqAnguarTol = 1.0e-16; + const gp_Dir &aNormal = aSurf->Axis().Direction(); + + // Obtain free-edges from myPipeShell. All edges must be planar + // and parallel to the plane of mySpine + + TopTools_IndexedDataMapOfShapeListOfShape aMap; + + TopExp::MapShapesAndAncestors(myPipeShell, TopAbs_EDGE, TopAbs_FACE, aMap); + + TopTools_ListOfShape aLE; + + gp_Pnt aP; + gp_Vec aTan; + + for (Standard_Integer i = 1; i <= aMap.Size(); i++) + { + TopTools_ListOfShape& aListF = aMap(i); + + if (aListF.Extent() != 1) + continue; + + const TopoDS_Edge &anE = TopoDS::Edge(aMap.FindKey(i)); + + BRepAdaptor_Curve anAC(anE); + if (!anAC.Is3DCurve()) + { + // We are not interested in degenerated edges. + continue; + } + + anAC.D1(0.5*(anAC.FirstParameter() + anAC.LastParameter()), aP, aTan); + + const Standard_Real aSqModulus = aTan.SquareMagnitude(); + if (aSqModulus < Precision::Confusion()) + continue; + + const Standard_Real aDP = aTan.XYZ().Dot(aNormal.XYZ()); + if (aDP*aDP>aSqModulus*aSqAnguarTol) + { + //Only planar edges are considered + continue; + } + + aLE.Append(anE); + } + + if (aLE.IsEmpty()) + { + myErrorStatus = BRepFill_Voluved_NotPlanarSpine; + return; + } + + // Split interfered edges + BOPAlgo_PaveFiller aPF; + aPF.SetArguments(aLE); + aPF.SetRunParallel(myIsParallel); + + aPF.Perform(); + if (aPF.HasErrors()) + { + myErrorStatus = BRepFill_Voluved_NotPlanarSpine; + return; + } + + BOPAlgo_Builder aBuilder; + TopTools_ListIteratorOfListOfShape aItLE(aLE); + for (; aItLE.More(); aItLE.Next()) + { + const TopoDS_Shape& aS = aItLE.Value(); + aBuilder.AddArgument(aS); + } + + aBuilder.SetRunParallel(myIsParallel); + aBuilder.PerformWithFiller(aPF); + if (aBuilder.HasErrors()) + { + myErrorStatus = BRepFill_Voluved_NotPlanarSpine; + return; + } + + const TopoDS_Shape& aFreeEdges = aBuilder.Shape(); + + // Collect all free edges to wires and create planar + // top and bottom lids from these wires. + BRep_Builder aBB; + TopoDS_Compound aCompW; + aBB.MakeCompound(aCompW); + aBB.MakeCompound(myTopBottom); + BOPAlgo_Tools::EdgesToWires(aFreeEdges, aCompW, Standard_True); + BOPAlgo_Tools::WiresToFaces(aCompW, myTopBottom); + + myErrorStatus = BRepFill_Voluved_NotSolid; +} + +//======================================================================= +//function : ProcessVertex +//purpose : +//======================================================================= +#include +#include +void ProcessVertex(const TopoDS_Vertex& aV, + const TopTools_ListOfShape& aLE, + const TopTools_ListOfShape& aLF) +{ + Standard_Real aTol, aD2, aTolMax2, aTolE, aParam; + gp_Pnt aPC3D; + gp_Pnt2d aPC2D; + TopAbs_Orientation anOrV; + + TopTools_ListIteratorOfListOfShape anIt; + TopExp_Explorer aVExp; + + BRep_ListIteratorOfListOfCurveRepresentation itcr; + // + aTolMax2 = -1.e6; + // + Handle(BRep_TVertex)& TV = *((Handle(BRep_TVertex)*) &aV.TShape()); + const gp_Pnt& aPV3D = TV->Pnt(); + aTol = BRep_Tool::Tolerance(aV); + // + anIt.Initialize(aLE); + for (; anIt.More(); anIt.Next()) + { + const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value()); + // + Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&aE.TShape()); + const TopLoc_Location& Eloc = aE.Location(); + // + aVExp.Init(aE, TopAbs_VERTEX); + for (; aVExp.More(); aVExp.Next()) + { + const TopoDS_Vertex& aVx = TopoDS::Vertex(aVExp.Current()); + // + if (!aVx.IsSame(aV)) + { + continue; + } + // + anOrV = aVx.Orientation(); + if (!(anOrV == TopAbs_FORWARD || anOrV == TopAbs_REVERSED)) + { + continue; + } + // + const BRep_ListOfCurveRepresentation& aLCR = TE->Curves(); + itcr.Initialize(aLCR); + for (; itcr.More(); itcr.Next()) + { + const Handle(BRep_CurveRepresentation)& cr = itcr.Value(); + const TopLoc_Location& loc = cr->Location(); + TopLoc_Location L = (Eloc * loc).Predivided(aV.Location()); + // + // 3D-Curve + if (cr->IsCurve3D()) + { + const Handle(Geom_Curve)& aC3D = cr->Curve3D(); + // + if (aC3D.IsNull()) + { + continue; + } + // 3D-point treatment + aParam = BRep_Tool::Parameter(aVx, aE); + aPC3D = aC3D->Value(aParam); + aPC3D.Transform(L.Transformation()); + aD2 = aPV3D.SquareDistance(aPC3D); + if (aD2 > aTolMax2) + { + aTolMax2 = aD2; + } + // + }//if (cr->IsCurve3D()) + // + // 2D-Curve + else if (cr->IsCurveOnSurface()) + { + const Handle(Geom2d_Curve)& aC2D = cr->PCurve(); + if (aC2D.IsNull()) + { + continue; + } + // Surface + const Handle(Geom_Surface)& aS = cr->Surface(); + // + // 2D-point treatment + aParam = BRep_Tool::Parameter(aVx, aE, aS, L); + aPC2D = aC2D->Value(aParam); + aS->D0(aPC2D.X(), aPC2D.Y(), aPC3D); + aPC3D.Transform(L.Transformation()); + aD2 = aPV3D.SquareDistance(aPC3D); + if (aD2 > aTolMax2) + { + aTolMax2 = aD2; + } + } //if (cr->IsCurveOnSurface()) + + }//for (; itcr.More(); itcr.Next()) + }//for (; aVExp.More(); aVExp.Next()) + }//for (; anIt.More(); anIt.Next()) + //######################################################### + // + // Reducing + if (aTolMax2<0.) + { + return; + } + // + aTolMax2 = sqrt(aTolMax2); + if (aTolMax2>aTol) + { + return; + } + // + anIt.Initialize(aLE); + for (; anIt.More(); anIt.Next()) + { + const TopoDS_Edge& aE = TopoDS::Edge(anIt.Value()); + + aTolE = BRep_Tool::Tolerance(aE); + if (aTolMax2 < aTolE) + { + aTolMax2 = aTolE; + } + } + // + anIt.Initialize(aLF); + for (; anIt.More(); anIt.Next()) + { + const TopoDS_Face& aF = TopoDS::Face(anIt.Value()); + + aTolE = BRep_Tool::Tolerance(aF); + if (aTolMax2 < aTolE) + { + aTolMax2 = aTolE; + } + } + // + if (aTolMax2>aTol) + { + return; + } + // + // Update Tolerance + TV->Tolerance(aTolMax2); +} + +//======================================================================= +//function : ReduceVertexTolerance +//purpose : +//======================================================================= +void ReduceVertexTolerance(const TopoDS_Shape& aS) +{ + Standard_Integer i, aNbV; + TopTools_IndexedDataMapOfShapeListOfShape aVEMap, aVFMap; + + TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_EDGE, aVEMap); + TopExp::MapShapesAndUniqueAncestors(aS, TopAbs_VERTEX, TopAbs_FACE, aVFMap); + + aNbV = aVEMap.Extent(); + for (i = 1; i <= aNbV; i++) + { + const TopoDS_Vertex& aV = TopoDS::Vertex(aVEMap.FindKey(i)); + const TopTools_ListOfShape& aLE = aVEMap(i); + const TopTools_ListOfShape& aLF = aVFMap.FindFromKey(aV); + + ProcessVertex(aV, aLE, aLF); + } +} + + +//======================================================================= +//function : BuildSolid +//purpose : +//======================================================================= +void BRepFill_Voluved::BuildSolid() +{ + if (myErrorStatus != BRepFill_Voluved_NotSolid) + return; + + myErrorStatus = BRepFill_Voluved_NotVolume; + + TopTools_MapOfShape aMapF; + TopTools_ListOfShape aLF, aLSplits; + TopExp_Explorer anExpF; + + Handle(ShapeFix_Shape) aSFix = new ShapeFix_Shape; + aSFix->Init(myPipeShell); + +#ifdef BREPFILL_VOLUVED_DEBUG + char aBuff[10000]; + Sprintf(aBuff, "%s%s", aDirPatch, "shape1.nbv"); + BinTools::Write(myPipeShell, aBuff); +#endif + + + aSFix->Perform(); + myPipeShell = aSFix->Shape(); + +#ifdef BREPFILL_VOLUVED_DEBUG + Sprintf(aBuff, "%s%s", aDirPatch, "shape2.nbv"); + BinTools::Write(myPipeShell, aBuff); +#endif + + for (anExpF.Init(myPipeShell, TopAbs_FACE); + anExpF.More(); anExpF.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anExpF.Current()); + if (!aMapF.Add(aF)) + continue; + + TopoDS_Face aFC = aF; + aSFix->Init(aFC); + aSFix->Perform(); + aFC = TopoDS::Face(aSFix->Shape()); + ReduceVertexTolerance(aFC); + + CheckSingularityAndAdd(aFC, myFuzzyValue, aLF, aLSplits); + } + + { + TopTools_ListIteratorOfListOfShape anItrS(aLSplits); + for (; anItrS.More(); anItrS.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItrS.Value()); + aLF.Append(aF); + } + +#ifdef BREPFILL_VOLUVED_DEBUG + BRep_Builder aBB; + TopoDS_Compound aDebComp; + aBB.MakeCompound(aDebComp); + TopTools_ListIteratorOfListOfShape anItrDeb(aLF); + for (; anItrDeb.More(); anItrDeb.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItrDeb.Value()); + aBB.Add(aDebComp, aF); + } + + Sprintf(aBuff, "%s%s", aDirPatch, "shape3.nbv"); + BinTools::Write(aDebComp, aBuff); +#endif + + // Split interfered faces + BOPAlgo_PaveFiller aPF; + aPF.SetArguments(aLF); + aPF.SetRunParallel(myIsParallel); + aPF.SetFuzzyValue(myFuzzyValue); + + aPF.Perform(); + if (!aPF.HasErrors()) + { + BOPAlgo_Builder aBuilder; + TopTools_ListIteratorOfListOfShape aItLE(aLF); + for (; aItLE.More(); aItLE.Next()) + { + const TopoDS_Shape& aS = aItLE.Value(); + aBuilder.AddArgument(aS); + } + + aBuilder.SetRunParallel(myIsParallel); + aBuilder.PerformWithFiller(aPF); + myPipeShell = aBuilder.Shape(); + } + } + +#ifdef BREPFILL_VOLUVED_DEBUG + Sprintf(aBuff, "%s%s", aDirPatch, "shape4.nbv"); + BinTools::Write(myPipeShell, aBuff); +#endif + + aLF.Clear(); + aMapF.Clear(); + for (anExpF.Init(myPipeShell, TopAbs_FACE); + anExpF.More(); anExpF.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anExpF.Current()); + if (!aMapF.Add(aF)) + continue; + + aLF.Append(aF); + } + + if (!myTopBottom.IsNull()) + { + TopoDS_Iterator anItLids(myTopBottom); + for (; anItLids.More(); anItLids.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItLids.Value()); + aLF.Append(aF); + } + } + +#ifdef BREPFILL_VOLUVED_DEBUG + BRep_Builder aBB; + TopoDS_Compound aDebComp; + aBB.MakeCompound(aDebComp); + TopTools_ListIteratorOfListOfShape anItrDeb(aLF); + for (; anItrDeb.More(); anItrDeb.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItrDeb.Value()); + aBB.Add(aDebComp, aF); + } + + Sprintf(aBuff, "%s%s", aDirPatch, "shape5.nbv"); + BinTools::Write(aDebComp, aBuff); +#endif + + BOPAlgo_MakerVolume aMV; + aMV.SetArguments(aLF); + aMV.SetFuzzyValue(myFuzzyValue); + aMV.SetIntersect(Standard_True); + aMV.SetRunParallel(myIsParallel); + aMV.SetAvoidInternalShapes(Standard_True); + aMV.Perform(); + + if (aMV.HasErrors()) + { + return; + } + + myResult = aMV.Shape(); + +#ifdef BREPFILL_VOLUVED_DEBUG + std::cout << "BuildSolid After VM." << std::endl; +#endif + + RemoveExcessSolids(aLSplits, myResult, aLF, aMV); + + myErrorStatus = BRepFill_Voluved_OK; +} + +//======================================================================= +//function : ExtractOuterSolid +//purpose : +//======================================================================= +void BRepFill_Voluved::ExtractOuterSolid(TopoDS_Shape& theShape, + TopTools_ListOfShape& theArgsList) +{ + TopTools_IndexedDataMapOfShapeListOfShape aMapS; + TopExp::MapShapesAndAncestors(theShape, TopAbs_FACE, TopAbs_SOLID, aMapS); + + Standard_Boolean hasBeenDeleted = Standard_False; + + for (Standard_Integer i = 1; i <= aMapS.Extent(); i++) + { + const TopTools_ListOfShape &aL = aMapS(i); + if (aL.Extent() > 1) + { + // Face is shared between several solids. ==> + // It cannot participate in the outer contour and should be removed. + + const TopoDS_Face &aF = TopoDS::Face(aMapS.FindKey(i)); + theArgsList.Remove(aF); + hasBeenDeleted = Standard_True; + } + } + + if (!hasBeenDeleted) + return; + + BOPAlgo_MakerVolume aMV; + aMV.SetArguments(theArgsList); + aMV.SetIntersect(Standard_True); + aMV.SetRunParallel(myIsParallel); + aMV.SetAvoidInternalShapes(Standard_True); + aMV.Perform(); + + if (aMV.HasErrors()) + { + return; + } + + theShape = aMV.Shape(); +} + +//======================================================================= +//function : RemoveExcessSolids +//purpose : +//======================================================================= +#include +#include +void BRepFill_Voluved::RemoveExcessSolids(const TopTools_ListOfShape& /*theLSplits*/, + TopoDS_Shape& theShape, + TopTools_ListOfShape& /*theArgsList*/, + BOPAlgo_MakerVolume& /*theMV*/) +{ + if (myErrorStatus != BRepFill_Voluved_NotVolume) + return; + +#if 1 + TopExp_Explorer anExpSo(theShape, TopAbs_SOLID); + Standard_Real aMaxVol = RealFirst(); + myResult = anExpSo.Current(); + for(;anExpSo.More(); anExpSo.Next()) + { + const TopoDS_Solid &aSol = TopoDS::Solid(anExpSo.Current()); + GProp_GProps aGprop; + BRepGProp::VolumeProperties(aSol, aGprop, 1.0e-4); + const Standard_Real aV = aGprop.Mass(); + + if(aV > aMaxVol) + { + aMaxVol = aV; + myResult = aSol; + } + } +#else + + TopExp_Explorer anExpSo; + for (Standard_Integer i = 0; i < 2; i++) + { + anExpSo.Init(theShape, TopAbs_SOLID); + if (!anExpSo.More()) + { + myResult = theShape; + return; + } + + anExpSo.Next(); + if (!anExpSo.More()) + { + // Only one solid has been generated + myResult = TopoDS::Solid(anExpSo.Current()); + return; + } + + if (i != 0) + break; + + ExtractOuterSolid(theShape, theArgsList); + } + + // Remove Split faces from the list of arguments + TopTools_ListIteratorOfListOfShape anItl(theLSplits); + for (; anItl.More(); anItl.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItl.Value()); + theArgsList.Remove(aF); + } + + // Create a list of invalid faces. The face is invalid if + // BOPAlgo_MakerVolume changes its orientation while creating solids. + // Faces from theLSplits are not checked. + TopTools_ListOfShape aListInvFaces; + for (anItl.Init(theArgsList); anItl.More(); anItl.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItl.Value()); + for (TopTools_ListIteratorOfListOfShape anItM(theMV.Modified(aF)); + anItM.More(); anItM.Next()) + { + const TopoDS_Face &aFM = TopoDS::Face(anItM.Value()); + + if (aFM.Orientation() != aF.Orientation()) + aListInvFaces.Append(aFM); + } + } + + TopTools_ListOfShape aSolidList; + for (anExpSo.Init(theShape, TopAbs_SOLID); anExpSo.More(); anExpSo.Next()) + { + const TopoDS_Solid &aSo = TopoDS::Solid(anExpSo.Current()); + TopTools_IndexedMapOfShape aMapF; + TopExp::MapShapes(aSo, TopAbs_FACE, aMapF); + Standard_Boolean isToDelete = Standard_False; + + for (anItl.Init(aListInvFaces); anItl.More(); anItl.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItl.Value()); + if (aMapF.Contains(aF)) + { + isToDelete = Standard_True; + break; + } + } + + if (isToDelete) + { + continue; + } + + for (anItl.Init(theArgsList); anItl.More(); anItl.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItl.Value()); + const Standard_Integer anIdx = aMapF.FindIndex(aF); + if (anIdx == 0) + continue; + + const TopoDS_Face &aF1 = TopoDS::Face(aMapF.FindKey(anIdx)); + + // aF and aF1 are same shapes. Check if they are equal. + + if (!aF.IsEqual(aF1)) + { + isToDelete = Standard_True; + break; + } + } + + if (isToDelete) + { + continue; + } + + aSolidList.Append(aSo); + } + + if (aSolidList.Extent() < 1) + { + myResult = theShape; + return; + } + + if (aSolidList.Extent() == 1) + { + myResult = aSolidList.First(); + return; + } + + BRep_Builder aBB; + TopoDS_Compound aCmpSol; + aBB.MakeCompound(aCmpSol); + + for (anItl.Init(aSolidList); anItl.More(); anItl.Next()) + { + const TopoDS_Solid &aSo = TopoDS::Solid(anItl.Value()); + aBB.Add(aCmpSol, aSo); + } + + myResult = aCmpSol; +#endif +} + +//======================================================================= +//class : NormalFunc +//purpose : +//======================================================================= +class NormalFunc : public math_MultipleVarFunctionWithHessian +{ +public: + NormalFunc(const Adaptor3d_CurveOnSurface& theCOS) :myCOnS(theCOS) + { + } + + virtual Standard_Integer NbVariables() const Standard_OVERRIDE + { + return 1; + } + + + virtual Standard_Boolean Value(const math_Vector& X, Standard_Real& F) Standard_OVERRIDE; + virtual Standard_Boolean Gradient(const math_Vector& X, math_Vector& G) Standard_OVERRIDE; + virtual Standard_Boolean Values(const math_Vector& theX, + Standard_Real& theF, + math_Vector& theG) Standard_OVERRIDE + { + if (!Value(theX, theF)) + return Standard_False; + + if (!Gradient(theX, theG)) + return Standard_False; + + return Standard_True; + }; + + virtual Standard_Boolean Values(const math_Vector& theX, + Standard_Real& theF, + math_Vector& theG, + math_Matrix& theH) Standard_OVERRIDE + { + if (!Values(theX, theF, theG)) + return Standard_False; + + theH(1, 1) = theG(1); + return Standard_True; + }; + + Standard_Real FirstParameter() const + { + return myCOnS.FirstParameter(); + } + + Standard_Real LastParameter() const + { + return myCOnS.LastParameter(); + } + + gp_Pnt GetPoint(const Standard_Real theX) + { + const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve(); + const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface(); + const gp_Pnt2d aP2d(aC->Value(theX)); + return aS->Value(aP2d.X(), aP2d.Y()); + } + +protected: + + NormalFunc& operator=(NormalFunc&); + +private: + const Adaptor3d_CurveOnSurface& myCOnS; +}; + +//======================================================================= +//function : Value +//purpose : +aD1v_x^2*aD1u_y^2 + aD1v_x^2*aD1u_z^2 + +// +aD1v_y^2*aD1u_z^2 + aD1u_x^2*aD1v_y^2 + +// +aD1u_x^2*aD1v_z^2 + aD1u_y^2*aD1v_z^2 - +// - 2*(+aD1u_x*aD1v_x*aD1u_y*aD1v_y + +// +aD1u_x*aD1v_x*aD1u_z*aD1v_z + +// +aD1u_y*aD1v_y*aD1u_z*aD1v_z) +//======================================================================= +Standard_Boolean NormalFunc::Value(const math_Vector& theX, Standard_Real& theF) +{ + const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve(); + const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface(); + + const gp_Pnt2d aP2d(aC->Value(theX(1))); + gp_Pnt aP3d; + gp_Vec aD1u, aD1v; + aS->D1(aP2d.X(), aP2d.Y(), aP3d, aD1u, aD1v); + + theF = aD1u.Crossed(aD1v).SquareMagnitude(); + return Standard_True; +} + +//======================================================================= +//function : Gradient +//purpose : +//2 * ((aD1v_x*aD1u_y)*(aD1u_y*(aD2uv_x*aDc_x + aD2v_x*aDc_y) + aD1v_x*(aD2u_y*aDc_x + aD2uv_y*aDc_y)) + +// (aD1v_x*aD1u_z)*(aD1u_z*(aD2uv_x*aDc_x + aD2v_x*aDc_y) + aD1v_x*(aD2u_z*aDc_x + aD2uv_z*aDc_y)) + +// (aD1v_y*aD1u_z)*(aD1u_z*(aD2uv_y*aDc_x + aD2v_y*aDc_y) + aD1v_y*(aD2u_z*aDc_x + aD2uv_z*aDc_y)) + +// (aD1u_x*aD1v_y)*(aD1u_x*(aD2uv_y*aDc_x + aD2v_y*aDc_y) + aD1v_y*(aD2u_x*aDc_x + aD2uv_x*aDc_y)) + +// (aD1u_x*aD1v_z)*(aD1u_x*(aD2uv_z*aDc_x + aD2v_z*aDc_y) + aD1v_z*(aD2u_x*aDc_x + aD2uv_x*aDc_y)) + +// (aD1u_y*aD1v_z)*(aD1u_y*(aD2uv_z*aDc_x + aD2v_z*aDc_y) + aD1v_z*(aD2u_y*aDc_x + aD2uv_y*aDc_y)) - +// +// (aD2u_x*aDc_x + aD2uv_x*aDc_y)*aD1v_x*aD1u_y*aD1v_y - +// aD1u_x*(aD2uv_x*aDc_x + aD2v_x*aDc_y)*aD1u_y*aD1v_y - +// aD1u_x*aD1v_x*(aD2u_y*aDc_x + aD2uv_y*aDc_y)*aD1v_y - +// aD1u_x*aD1v_x*aD1u_y*(aD2uv_y*aDc_x + aD2v_y*aDc_y) - +// +// (aD2u_x*aDc_x + aD2uv_x*aDc_y)*aD1v_x*aD1u_z*aD1v_z - +// aD1u_x*(aD2uv_x*aDc_x + aD2v_x*aDc_y)*aD1u_z*aD1v_z - +// aD1u_x*aD1v_x*(aD2u_z*aDc_x + aD2uv_z*aDc_y)*aD1v_z - +// aD1u_x*aD1v_x*aD1u_z*(aD2uv_z*aDc_x + aD2v_z*aDc_y) - +// +// (aD2u_y*aDc_x + aD2uv_y*aDc_y)*aD1v_y*aD1u_z*aD1v_z - +// aD1u_y*(aD2uv_y*aDc_x + aD2v_y*aDc_y)*aD1u_z*aD1v_z - +// aD1u_y*aD1v_y*(aD2u_z*aDc_x + aD2uv_z*aDc_y)*aD1v_z - +// aD1u_y*aD1v_y*aD1u_z*(aD2uv_z*aDc_x + aD2v_z*aDc_y)) +//======================================================================= +Standard_Boolean NormalFunc::Gradient(const math_Vector& theX, math_Vector& theG) +{ + const Handle(Adaptor2d_HCurve2d) &aC = myCOnS.GetCurve(); + const Handle(Adaptor3d_HSurface) &aS = myCOnS.GetSurface(); + + gp_Pnt2d aP2d; + gp_Vec2d aDc; + aC->D1(theX(1), aP2d, aDc); + + gp_Pnt aP3d; + gp_Vec aD1u, aD1v, aD2u, aD2v, aD2uv; + aS->D2(aP2d.X(), aP2d.Y(), aP3d, aD1u, aD1v, aD2u, aD2v, aD2uv); + + theG(1) = (aD1v.X()*aD1u.Y())*(aD1u.Y()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y()) + + aD1v.X()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())) + + (aD1v.X()*aD1u.Z())*(aD1u.Z()*(aD2uv.X()*aDc.X() + + aD2v.X()*aDc.Y()) + aD1v.X()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())) + + (aD1v.Y()*aD1u.Z())*(aD1u.Z()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) + + aD1v.Y()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())) + (aD1u.X()*aD1v.Y())* + (aD1u.X()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) + aD1v.Y()*(aD2u.X()* + aDc.X() + aD2uv.X()*aDc.Y())) + (aD1u.X()*aD1v.Z())*(aD1u.X()*(aD2uv.Z()* + aDc.X() + aD2v.Z()*aDc.Y()) + aD1v.Z()*(aD2u.X()*aDc.X() + + aD2uv.X()*aDc.Y())) + (aD1u.Y()*aD1v.Z())*(aD1u.Y()*(aD2uv.Z()*aDc.X() + + aD2v.Z()*aDc.Y()) + aD1v.Z()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())) - + (aD2u.X()*aDc.X() + aD2uv.X()*aDc.Y())*aD1v.X()*aD1u.Y()*aD1v.Y() - + aD1u.X()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y())*aD1u.Y()*aD1v.Y() - + aD1u.X()*aD1v.X()*(aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())*aD1v.Y() - + aD1u.X()*aD1v.X()*aD1u.Y()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y()) - + (aD2u.X()*aDc.X() + aD2uv.X()*aDc.Y())*aD1v.X()*aD1u.Z()*aD1v.Z() - + aD1u.X()*(aD2uv.X()*aDc.X() + aD2v.X()*aDc.Y())*aD1u.Z()*aD1v.Z() - + aD1u.X()*aD1v.X()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())*aD1v.Z() - + aD1u.X()*aD1v.X()*aD1u.Z()*(aD2uv.Z()*aDc.X() + aD2v.Z()*aDc.Y()) - + (aD2u.Y()*aDc.X() + aD2uv.Y()*aDc.Y())*aD1v.Y()*aD1u.Z()*aD1v.Z() - + aD1u.Y()*(aD2uv.Y()*aDc.X() + aD2v.Y()*aDc.Y())*aD1u.Z()*aD1v.Z() - + aD1u.Y()*aD1v.Y()*(aD2u.Z()*aDc.X() + aD2uv.Z()*aDc.Y())*aD1v.Z() - + aD1u.Y()*aD1v.Y()*aD1u.Z()*(aD2uv.Z()*aDc.X() + aD2v.Z()*aDc.Y()); + + return Standard_True; +} + +//======================================================================= +//structure : EInfoTosplit +//purpose : +//======================================================================= +struct EInfoTosplit +{ + TopoDS_Edge myEdge; + TopoDS_Vertex myVertexToSplit; + Standard_Real myParam; + Standard_Real myTolerance; +}; + +//======================================================================= +//function : RebuildFaces +//purpose : Creates a wires from theEdges and puts it to the new face +// which is empty-copied from theSourceFace. +//======================================================================= +static void RebuildFaces(const TopTools_ListOfShape& theLE, + const TopoDS_Face& theSourceFace, + TopTools_ListOfShape& theList) +{ + //build new faces + BOPAlgo_BuilderFace aBF; + + TopoDS_Face aF = TopoDS::Face(theSourceFace.Oriented(TopAbs_FORWARD)); + + aBF.SetFace(aF); + aBF.SetShapes(theLE); + + aBF.Perform(); + + const TopTools_ListOfShape& aLFR = aBF.Areas(); + + if (aLFR.IsEmpty()) + { + theList.Append(theSourceFace); + return; + } + + TopTools_ListIteratorOfListOfShape aItFR(aLFR); + for (; aItFR.More(); aItFR.Next()) + { + const TopoDS_Shape& aFR = TopoDS::Face(aItFR.Value()); + theList.Append(aFR); + } +} + +//======================================================================= +//function : MakeEdgeDegenerated +//purpose : Returns TRUE if degenerated edge has been created. +// Every degenerated edge (to split) must be added in theLEdges twice +// with different orientations. Moreover, Degenerated edges cannot be shared. +// Therefore, make copy of them before adding. +//======================================================================= +static Standard_Boolean MakeEdgeDegenerated(const TopoDS_Vertex& theV, + const TopoDS_Face& theFace, + const gp_Pnt2d& thePf, + const gp_Pnt2d& thePl, + TopTools_ListOfShape& theLEdges) +{ + BRepAdaptor_Surface anAS(theFace, Standard_False); + + const Standard_Real aTol = 2.0*BRep_Tool::Tolerance(theV); + const Standard_Real aTolU = anAS.UResolution(aTol), + aTolV = anAS.VResolution(aTol); + + if ((Abs(thePf.X() - thePl.X()) < aTolU) && (Abs(thePf.Y() - thePl.Y()) < aTolV)) + return Standard_False; + + const TopoDS_Vertex aVf = TopoDS::Vertex(theV.Oriented(TopAbs_FORWARD)), + aVl = TopoDS::Vertex(theV.Oriented(TopAbs_REVERSED)); + + const gp_XY aV = thePl.XY() - thePf.XY(); + const Handle(Geom2d_Line) aL1 = new Geom2d_Line(thePf, gp_Dir2d(aV)); + const Handle(Geom2d_Line) aL2 = new Geom2d_Line(thePl, gp_Dir2d(aV.Reversed())); + + BRep_Builder aBB; + TopoDS_Edge anEdegen1, anEdegen2; + aBB.MakeEdge(anEdegen1); + aBB.MakeEdge(anEdegen2); + + aBB.UpdateEdge(anEdegen1, aL1, theFace, Precision::Confusion()); + aBB.UpdateEdge(anEdegen2, aL2, theFace, Precision::Confusion()); + + anEdegen1.Orientation(TopAbs_FORWARD); + anEdegen2.Orientation(TopAbs_FORWARD); + + aBB.Add(anEdegen1, aVf); + aBB.Add(anEdegen1, aVl); + aBB.Add(anEdegen2, aVf); + aBB.Add(anEdegen2, aVl); + + aBB.Degenerated(anEdegen1, Standard_True); + aBB.Degenerated(anEdegen2, Standard_True); + + const Standard_Real aLPar = aV.Modulus(); + aBB.Range(anEdegen1, 0.0, aLPar); + aBB.Range(anEdegen2, 0.0, aLPar); + + theLEdges.Append(anEdegen1); + theLEdges.Append(anEdegen2); + + return Standard_True; +} + +//======================================================================= +//function : InsertEDegenerated +//purpose : +//======================================================================= +static void InsertEDegenerated(const TopoDS_Face& theFace, + TopTools_ListOfShape& theLEdges) +{ + BRep_Builder aBB; + TopoDS_Wire aWir; + aBB.MakeWire(aWir); + + TopTools_ListIteratorOfListOfShape anItr(theLEdges); + for (; anItr.More(); anItr.Next()) + { + const TopoDS_Edge &anE = TopoDS::Edge(anItr.Value()); + aBB.Add(aWir, anE); + } + + TopTools_IndexedDataMapOfShapeListOfShape aMapVE; + TopExp::MapShapesAndUniqueAncestors(aWir, TopAbs_VERTEX, TopAbs_EDGE, aMapVE); + + BRepTools_WireExplorer anExp(aWir, theFace); + + TopoDS_Edge anE1 = anExp.Current(), aFirstEdge, aLastEdge; + + if (anE1.IsNull()) + { + // It is possible if aWir contains + // only INTERNAL/EXTERNAL edges. + + return; + } + + aFirstEdge = anE1; + anExp.Next(); + +# if 0 + if (!anExp.More()) + { + // The wire contains only single edge. + // But this edge can be closed itself (e.g. circle). + + TopoDS_Vertex aVf, aVl; + TopExp::Vertices(anE1, aVf, aVl); + if (!aVf.IsNull() && aVf.IsSame(aVl)) + { + Standard_Real aF, aL; + const Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface(anE1, theFace, aF, aL); + aF = BRep_Tool::Parameter(aVf, anE1); + aL = BRep_Tool::Parameter(aVl, anE1); + const gp_Pnt2d aPf(aC->Value(aF)), aPl(aC->Value(aL)); + + MakeEdgeDegenerated(aVf, theFace, aPf, aPl, theLEdges); + } + + return; + } +#endif + + // Map containing all vertices of degenerated edges + TopTools_MapOfShape aMapVofDE; + + { + TopExp_Explorer anExpDE(aWir, TopAbs_EDGE); + for (; anExpDE.More(); anExpDE.Next()) + { + const TopoDS_Edge &anE = TopoDS::Edge(anExpDE.Current()); + if (!BRep_Tool::Degenerated(anE)) + continue; + + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(anE, aV1, aV2); + + // aV1 and aV2 are SAME vertices + + aMapVofDE.Add(aV1); + } + } + + for (; anExp.More(); anExp.Next()) + { + const TopoDS_Edge& anE2 = anExp.Current(); + aLastEdge = anE2; +#if 0 + if (anE1.IsSame(anE2)) + { + //Exclude a gap between two seam-edges (e.g. cylinder without roofs). + anE1 = anE2; + continue; + } +#endif + + const TopoDS_Vertex &aVertCurr = anExp.CurrentVertex(); + + if (aMapVofDE.Contains(aVertCurr)) + { + // Necessary degenerated edge has already been created. + anE1 = anE2; + continue; + } + + Standard_Real aF, aL; + const Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(anE1, theFace, aF, aL), + aC2 = BRep_Tool::CurveOnSurface(anE2, theFace, aF, aL); + aF = BRep_Tool::Parameter(aVertCurr, anE1); + aL = BRep_Tool::Parameter(aVertCurr, anE2); + const gp_Pnt2d aPf(aC1->Value(aF)), aPl(aC2->Value(aL)); + + if (MakeEdgeDegenerated(aVertCurr, theFace, aPf, aPl, theLEdges)) + { + aMapVofDE.Add(aVertCurr); + anE1 = anE2; + continue; + } + + const TopTools_ListOfShape *anEList = aMapVE.Seek(aVertCurr); + if ((anEList != 0) && (anEList->Extent() <= 2)) + { + anE1 = anE2; + continue; + } + + // Case like cone with apex. In 2D space all is OK + // (therefore BRepTools_WireExplorer processes this case + // correctly). But in 3D-space, we have several edges with + // the same vertex. Cone apex must be plugged by degenerated edge. + + Standard_Boolean hasDegenerated = Standard_False; + TopTools_ListIteratorOfListOfShape anItr(*anEList); + for (; anItr.More(); anItr.Next()) + { + const TopoDS_Edge &anEdge = TopoDS::Edge(anItr.Value()); + if (BRep_Tool::Degenerated(anEdge)) + { + hasDegenerated = Standard_True; + break; + } + } + + if (hasDegenerated) + { + anE1 = anE2; + continue; + } + + // Look for the pair for anE1 and anE2 edges + for (Standard_Integer i = 0; i < 2; i++) + { + const gp_Pnt2d &aPoint = i ? aPl : aPf; + anItr.Initialize(*anEList); + for (; anItr.More(); anItr.Next()) + { + const TopoDS_Edge &anEdge = TopoDS::Edge(anItr.Value()); + + if (anEdge.IsSame(anE1) || anEdge.IsSame(anE2)) + continue; + + const Handle(Geom2d_Curve) aC = BRep_Tool::CurveOnSurface(anEdge, theFace, aF, aL); + aF = BRep_Tool::Parameter(aVertCurr, anEdge); + const gp_Pnt2d aP(aC->Value(aF)); + + if (MakeEdgeDegenerated(aVertCurr, theFace, aPoint, aP, theLEdges)) + { + aMapVofDE.Add(aVertCurr); + i = 2; + break; + } + } + } + + anE1 = anE2; + } + + if (aFirstEdge.IsNull() || aLastEdge.IsNull()) + return; + +#if 0 + if (aFirstEdge.IsSame(aLastEdge)) + { + //Exclude a gap between two seam-edges (e.g. cylinder without bottom-base). + + return; + } +#endif + + //TopExp::CommonVertex(...) does not work + //if edges have more than one pair of common vertex + //(e.g. two halves of circle). Here, we process this case. + TopoDS_Vertex aV[4]; + TopExp::Vertices(aFirstEdge, aV[0], aV[1]); + if (!aV[0].IsNull() && aV[0].IsSame(aV[1])) + { + // Possible reason is the NOT-CLOSED edge + // has only single vertex and is covered by it. + return; + } + + TopExp::Vertices(aLastEdge, aV[2], aV[3]); + if (!aV[2].IsNull() && aV[2].IsSame(aV[3])) + { + // Possible reason is the NOT-CLOSED edge + // has only single vertex and is covered by it. + return; + } + + for (Standard_Integer anIDFE = 0; anIDFE < 2; anIDFE++) + { + for (Standard_Integer anIDLE = 2; anIDLE < 4; anIDLE++) + { + if (!aV[anIDFE].IsSame(aV[anIDLE])) + continue; + + const NCollection_List *anEList = aMapVE.Seek(aV[anIDFE]); + if ((anEList != 0) && (anEList->Extent() > 2)) + { + // Causes: + // 1. Non-manifold topology. + // 2. Case such as: + // + // ************************* + // * * + // seam * * seam + // * edge1 edge2 * + // * ******** ********* * + // V1 V2 V3 V4 + // + // + // V1 - vertex between edge1 and seam + // V4 - vertex between edge2 and seam + // + // Indeed, V1 and V4 are same but they + // must not be joined. + + continue; + } + + Standard_Real aF, aL; + const Handle(Geom2d_Curve) aC1 = BRep_Tool::CurveOnSurface(aFirstEdge, theFace, aF, aL), + aC2 = BRep_Tool::CurveOnSurface(aLastEdge, theFace, aF, aL); + aF = BRep_Tool::Parameter(aV[anIDFE], aFirstEdge); + aL = BRep_Tool::Parameter(aV[anIDLE], aLastEdge); + const gp_Pnt2d aPf(aC1->Value(aF)), aPl(aC2->Value(aL)); + + MakeEdgeDegenerated(aV[anIDFE], theFace, aPf, aPl, theLEdges); + } + } +} + +//======================================================================= +//function : CheckSingularityAndAdd +//purpose : Returns TRUE if theF has been split +//======================================================================= +Standard_Boolean BRepFill_Voluved::CheckSingularityAndAdd(const TopoDS_Face& theF, + const Standard_Real theFuzzyToler, + TopTools_ListOfShape& theListOfFaces, + TopTools_ListOfShape& theListOfSplits) const +{ + const BRepAdaptor_Surface anAS(theF, Standard_False); + GeomAbs_SurfaceType aSType = anAS.GetType(); + + if (aSType == GeomAbs_OffsetSurface) + { + aSType = anAS.BasisSurface()->GetType(); + } + + if (aSType == GeomAbs_Plane) + { + TopTools_MapOfShape aME; + TopTools_ListOfShape aLE; + TopExp_Explorer anExp(theF, TopAbs_EDGE); + for (; anExp.More(); anExp.Next()) + { + const TopoDS_Edge &anE = TopoDS::Edge(anExp.Current()); + + if (aME.Add(anE)) + aLE.Append(anE); + } + + // Split interfered edges + BOPAlgo_PaveFiller aPF; + aPF.SetArguments(aLE); + aPF.SetRunParallel(myIsParallel); + + aPF.Perform(); + if (aPF.HasErrors()) + { + theListOfFaces.Append(theF); + return Standard_False; + } + + const BOPDS_DS &aDS = aPF.DS(); + if (aDS.NbShapes() == aDS.NbSourceShapes()) + { + //Interfered edges have not been detected + theListOfFaces.Append(theF); + return Standard_False; + } + + BOPAlgo_Builder aBuilder; + TopTools_ListIteratorOfListOfShape aItLE(aLE); + for (; aItLE.More(); aItLE.Next()) + { + const TopoDS_Shape& aS = aItLE.Value(); + aBuilder.AddArgument(aS); + } + + aBuilder.SetRunParallel(myIsParallel); + aBuilder.PerformWithFiller(aPF); + if (aBuilder.HasErrors()) + { + theListOfFaces.Append(theF); + return Standard_False; + } + + const TopoDS_Shape& anEdges = aBuilder.Shape(); + + BRep_Builder aBB; + TopoDS_Compound aCompW, aCompF; + aBB.MakeCompound(aCompW); + aBB.MakeCompound(aCompF); + BOPAlgo_Tools::EdgesToWires(anEdges, aCompW, Standard_True); + BOPAlgo_Tools::WiresToFaces(aCompW, aCompF); + + aME.Clear(); + anExp.Init(aCompF, TopAbs_FACE); + for (; anExp.More(); anExp.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anExp.Current()); + theListOfSplits.Append(aF); + } + + return Standard_True; + } + + if ((aSType != GeomAbs_Cone) && + (aSType != GeomAbs_Sphere) && + (aSType != GeomAbs_BezierSurface) && + (aSType != GeomAbs_BSplineSurface) && + (aSType != GeomAbs_SurfaceOfRevolution)) + { + theListOfFaces.Append(theF); + return Standard_False; + } + + BRep_Builder aBB; + + TopoDS_Compound aCWires; + aBB.MakeCompound(aCWires); + + Standard_Boolean isSplit = Standard_False; + TopTools_ListOfShape aListEdges; + + const TopoDS_Face aF = TopoDS::Face(theF.Oriented(TopAbs_FORWARD)); + + for (TopoDS_Iterator anExpW(aF); anExpW.More(); anExpW.Next()) + { + const TopoDS_Wire &aWir = TopoDS::Wire(anExpW.Value()); + + TopTools_ListOfShape aLGF; + TopExp_Explorer anEExp(aWir, TopAbs_EDGE); + for (; anEExp.More(); anEExp.Next()) + { + const TopoDS_Edge &anE = TopoDS::Edge(anEExp.Current()); + aLGF.Append(anE); + } + + BOPAlgo_PaveFiller aPF; + aPF.SetArguments(aLGF); + aPF.SetFuzzyValue(theFuzzyToler); + aPF.Perform(); + + if (aPF.HasErrors()) + { + continue; + } + + const BOPDS_DS &aDS = aPF.DS(); + if (aDS.NbShapes() == aDS.NbSourceShapes()) + { + //No new shapes have been created + continue; + } + + BOPAlgo_Builder aBAB(NCollection_BaseAllocator::CommonBaseAllocator()); + TopTools_ListIteratorOfListOfShape aBItr(aLGF); + for (; aBItr.More(); aBItr.Next()) + { + const TopoDS_Shape &aSh = aBItr.Value(); + aBAB.AddArgument(aSh); + } + + aBAB.SetRunParallel(myIsParallel); + aBAB.SetNonDestructive(Standard_True); + aBAB.PerformWithFiller(aPF); + if (aBAB.HasErrors()) + { + continue; + } + + TopTools_ListOfShape aLE; +#if 0 + // This fragment requires fixing the issue #29656 + TopTools_MapOfShape aMM; + TopExp_Explorer anExpEB(aBAB.Shape(), TopAbs_EDGE); + for (; anExpEB.More(); anExpEB.Next()) + { + const TopoDS_Edge anEE = TopoDS::Edge(anExpEB.Current()); + if (!aMM.Add(anEE)) + continue; + + aLE.Append(anEE); + } +#else + for (aBItr.Init(aLGF); aBItr.More(); aBItr.Next()) + { + const TopoDS_Edge &aSh = TopoDS::Edge(aBItr.Value()); + const TopTools_ListOfShape &aLM = aBAB.Modified(aSh); + if (aLM.IsEmpty() || BRep_Tool::Degenerated(aSh)) + { + aLE.Append(aSh); + continue; + } + + TopTools_ListIteratorOfListOfShape anItLM(aLM); + for (; anItLM.More(); anItLM.Next()) + { + const TopoDS_Edge &anEM = TopoDS::Edge(anItLM.Value()); + aLE.Append(anEM); + } + } +#endif + + isSplit = Standard_True; + InsertEDegenerated(aF, aLE); + aListEdges.Append(aLE); + } + + if (!isSplit) + { + theListOfFaces.Append(theF); + return Standard_False; + } + + RebuildFaces(aListEdges, theF, theListOfSplits); + + TopTools_ListIteratorOfListOfShape anItrS(theListOfSplits); + for (; anItrS.More(); anItrS.Next()) + { + const TopoDS_Face &aF = TopoDS::Face(anItrS.Value()); + theListOfFaces.Append(aF.Oriented(theF.Orientation())); + } + + return Standard_True; +} diff --git a/src/BRepFill/BRepFill_Voluved.hxx b/src/BRepFill/BRepFill_Voluved.hxx new file mode 100644 index 0000000000..39c1ca7295 --- /dev/null +++ b/src/BRepFill/BRepFill_Voluved.hxx @@ -0,0 +1,120 @@ +// Created on: 2018-03-14 +// Created by: Nikolai BUKHALOV +// Copyright (c) 1999-2018 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef _BRepFill_Voluved_HeaderFile +#define _BRepFill_Voluved_HeaderFile + +#include +#include +#include + +#include +#include +#include +#include +class BOPAlgo_MakerVolume; +class TopoDS_Face; + +//! Constructs an evolved volume from a spine (wire or face) +//! and a profile ( wire). +class BRepFill_Voluved +{ +public: + + DEFINE_STANDARD_ALLOC + + Standard_EXPORT BRepFill_Voluved() :myErrorStatus(BRepFill_Voluved_Empty), + myFuzzyValue(0.0), + myIsParallel(Standard_True) + { + } + + Standard_EXPORT void Perform(const TopoDS_Wire& theSpine, const TopoDS_Wire& theProfile, const Standard_Real theTolerance, const Standard_Boolean theSolidReq = Standard_True); + + Standard_Boolean IsDone(unsigned int* theErrorCode = 0) const + { + if (theErrorCode) + *theErrorCode = myErrorStatus; + + return (myErrorStatus == BRepFill_Voluved_OK); + } + + //! returns the resulting shape. + const TopoDS_Shape& Shape() const + { + return myResult; + } + + //! Triggers computation mode between Parallel/Single-thread + void SetRunParallel(Standard_Boolean theValue) + { + myIsParallel = theValue; + } + +protected: + + Standard_EXPORT void PerformSweep(); + + Standard_EXPORT void GetLids(); + + Standard_EXPORT void BuildSolid(); + + Standard_EXPORT void RemoveExcessSolids(const TopTools_ListOfShape& theLSplits, + TopoDS_Shape& theShape, + TopTools_ListOfShape& theArgsList, + BOPAlgo_MakerVolume& theMV); + + Standard_EXPORT void ExtractOuterSolid(TopoDS_Shape& theShape, + TopTools_ListOfShape& theArgsList); + + Standard_EXPORT void GetSpineAndProfile(const TopoDS_Wire& theSpine, + const TopoDS_Wire& theProfile); + + Standard_EXPORT Standard_Boolean CheckSingularityAndAdd(const TopoDS_Face& theF, + const Standard_Real theFuzzyToler, + TopTools_ListOfShape& theListOfFaces, + TopTools_ListOfShape& theListOfSplits) const; + + +private: + + enum + { + BRepFill_Voluved_Empty = 0, + BRepFill_Voluved_NotPlanarSpine, + BRepFill_Voluved_SweepError, + BRepFill_Voluved_NoLids, + BRepFill_Voluved_NotSolid, + BRepFill_Voluved_NotVolume, + BRepFill_Voluved_OK = UINT_MAX + } myErrorStatus; + + TopoDS_Wire mySpine; + TopoDS_Wire myProfile; + TopoDS_Shape myPipeShell; + TopoDS_Compound myTopBottom; // Lids can be split on several faces + TopoDS_Shape myResult; + Standard_Real myFuzzyValue; + Standard_Boolean myIsParallel; + +}; + + + + + + + +#endif // _BRepFill_Voluved_HeaderFile diff --git a/src/BRepFill/FILES b/src/BRepFill/FILES index ebba998dd6..e0a9ded7a0 100644 --- a/src/BRepFill/FILES +++ b/src/BRepFill/FILES @@ -83,3 +83,5 @@ BRepFill_TrimShellCorner.hxx BRepFill_TrimSurfaceTool.cxx BRepFill_TrimSurfaceTool.hxx BRepFill_TypeOfContact.hxx +BRepFill_Voluved.cxx +BRepFill_Voluved.hxx \ No newline at end of file diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.cxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.cxx index 10310e689d..50e4b0ca2c 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.cxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.cxx @@ -22,6 +22,8 @@ #include #include #include +#include +#include //======================================================================= //function : BRepOffsetAPI_MakeEvolved @@ -43,19 +45,31 @@ BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Wire& Spin const Standard_Boolean AxeProf, const Standard_Boolean Solid, const Standard_Boolean ProfOnSpine, - const Standard_Real Tol) + const Standard_Boolean theIsVolume, + const Standard_Real Tol, + const Standard_Boolean theRunInParallel) { - gp_Ax3 Axis(gp_Pnt(0.,0.,0.), - gp_Dir(0.,0.,1.), - gp_Dir(1.,0.,0.)); - - if ( !AxeProf) { - Standard_Boolean POS; - BRepFill::Axe(Spine,Profil,Axis,POS,Tol); - if (ProfOnSpine && !POS) return; + if (theIsVolume) + { + myVolume.SetRunParallel(theRunInParallel); + myVolume.Perform(Spine, Profil, Tol); + } + else + { + gp_Ax3 Axis(gp_Pnt(0., 0., 0.), + gp_Dir(0., 0., 1.), + gp_Dir(1., 0., 0.)); + + if (!AxeProf) + { + Standard_Boolean POS; + BRepFill::Axe(Spine, Profil, Axis, POS, Max(Tol, Precision::Confusion())); + if (ProfOnSpine && !POS) return; + } + + myEvolved.Perform(Spine, Profil, Axis, Join, Solid); } - myEvolved.Perform(Spine,Profil,Axis,Join,Solid); Build(); Done(); } @@ -72,20 +86,33 @@ BRepOffsetAPI_MakeEvolved::BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spin const Standard_Boolean AxeProf, const Standard_Boolean Solid, const Standard_Boolean ProfOnSpine, - const Standard_Real Tol) + const Standard_Boolean theIsVolume, + const Standard_Real Tol, + const Standard_Boolean theRunInParallel) { - gp_Ax3 Axis(gp_Pnt(0.,0.,0.), - gp_Dir(0.,0.,1.), - gp_Dir(1.,0.,0.)); - - if ( !AxeProf) { - Standard_Boolean POS; - BRepFill::Axe(Spine,Profil,Axis,POS,Tol); - if (ProfOnSpine && !POS) return; + if (theIsVolume) + { + myVolume.SetRunParallel(theRunInParallel); + myVolume.Perform(TopoDS::Wire(TopoDS_Iterator(Spine).Value()), Profil, Tol); + } + else + { + gp_Ax3 Axis(gp_Pnt(0., 0., 0.), + gp_Dir(0., 0., 1.), + gp_Dir(1., 0., 0.)); + + if (!AxeProf) + { + Standard_Boolean POS; + BRepFill::Axe(Spine, Profil, Axis, POS, Max(Tol, Precision::Confusion())); + if (ProfOnSpine && !POS) return; + } + + myEvolved.Perform(Spine, Profil, Axis, Join, Solid); } - myEvolved.Perform(Spine,Profil,Axis,Join,Solid); Build(); + Done(); } @@ -107,8 +134,16 @@ const BRepFill_Evolved& BRepOffsetAPI_MakeEvolved::Evolved() const void BRepOffsetAPI_MakeEvolved::Build() { - myShape = myEvolved.Shape(); - if (myEvolved.IsDone()) Done(); + if (myEvolved.IsDone()) + { + myShape = myEvolved.Shape(); + } + else if (myVolume.IsDone()) + { + myShape = myVolume.Shape(); + } + + Done(); } diff --git a/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.hxx b/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.hxx index fc778e36a0..3a5129bdf4 100644 --- a/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.hxx +++ b/src/BRepOffsetAPI/BRepOffsetAPI_MakeEvolved.hxx @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -66,7 +67,7 @@ public: Standard_EXPORT BRepOffsetAPI_MakeEvolved(); - Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Wire& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join = GeomAbs_Arc, const Standard_Boolean AxeProf = Standard_True, const Standard_Boolean Solid = Standard_False, const Standard_Boolean ProfOnSpine = Standard_False, const Standard_Real Tol = 0.0000001); + Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Wire& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join/* = GeomAbs_Arc*/, const Standard_Boolean AxeProf/* = Standard_True*/, const Standard_Boolean Solid/* = Standard_False*/, const Standard_Boolean ProfOnSpine/* = Standard_False*/, const Standard_Boolean theIsVolume, const Standard_Real Tol/* = Precision::Confusion()*/, const Standard_Boolean theRunInParallel); //! These constructors construct an evolved shape by sweeping the profile //! Profile along the spine Spine. @@ -88,7 +89,7 @@ public: //! axis passing along the vertex and the normal to the //! plane of the spine. At present, this is the only //! construction type implemented. - Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join = GeomAbs_Arc, const Standard_Boolean AxeProf = Standard_True, const Standard_Boolean Solid = Standard_False, const Standard_Boolean ProfOnSpine = Standard_False, const Standard_Real Tol = 0.0000001); + Standard_EXPORT BRepOffsetAPI_MakeEvolved(const TopoDS_Face& Spine, const TopoDS_Wire& Profil, const GeomAbs_JoinType Join/* = GeomAbs_Arc*/, const Standard_Boolean AxeProf/* = Standard_True*/, const Standard_Boolean Solid/* = Standard_False*/, const Standard_Boolean ProfOnSpine/* = Standard_False*/, const Standard_Boolean theIsVolume, const Standard_Real Tol/* = Precision::Confusion()*/, const Standard_Boolean theRunInParallel); Standard_EXPORT const BRepFill_Evolved& Evolved() const; @@ -118,9 +119,8 @@ protected: private: - BRepFill_Evolved myEvolved; - + BRepFill_Voluved myVolume; }; diff --git a/src/BRepTest/BRepTest_SweepCommands.cxx b/src/BRepTest/BRepTest_SweepCommands.cxx index 8f3b51f120..64c8e27b8a 100644 --- a/src/BRepTest/BRepTest_SweepCommands.cxx +++ b/src/BRepTest/BRepTest_SweepCommands.cxx @@ -237,34 +237,94 @@ Standard_Integer evolved(Draw_Interpretor& di, Standard_Integer n, const char** if ( n < 4 ) return 1; Standard_Boolean IsAFace = Standard_False; - Standard_Boolean Solid = (!strcmp(a[0],"evolvedsolid")); + Standard_Boolean Solid = Standard_False; + Standard_Boolean isVolume = Standard_False; + Standard_Boolean hasToComputeAxes = Standard_False; + Standard_Real aTolerance = 0.0; + TopoDS_Shape Base; + TopoDS_Wire Prof; + Standard_Boolean isParallel = Standard_True; + + for (Standard_Integer i = 2; i < n; i++) + { + if (a[i][0] != '-') + { + di << "Error: wrong option!\n"; + return 1; + } + if (!strcmp(a[i], "-solid")) + { + Solid = Standard_True; + continue; + } - - TopoDS_Shape Base = DBRep::Get(a[2],TopAbs_WIRE,Standard_False); - if ( Base.IsNull()) { - Base = DBRep::Get(a[2],TopAbs_FACE,Standard_False); - IsAFace = Standard_True; - } - if ( Base.IsNull()) return 1; - - TopoDS_Shape InpuTShape(DBRep::Get(a[3],TopAbs_WIRE,Standard_False)); - TopoDS_Wire Prof = TopoDS::Wire(InpuTShape); -// TopoDS_Wire Prof = -// TopoDS::Wire(DBRep::Get(a[3],TopAbs_WIRE,Standard_False)); - if ( Prof.IsNull()) return 1; - - if (IsAFace) { - TopoDS_Shape Volevo - = BRepOffsetAPI_MakeEvolved(TopoDS::Face(Base),Prof,GeomAbs_Arc,n == 4,Solid); - DBRep::Set(a[1],Volevo); + if (!strcmp(a[i], "-stm")) + { + isParallel = Standard_False; + continue; + } + + switch (a[i][1]) + { + case 's': + { + Base = DBRep::Get(a[++i], TopAbs_WIRE, Standard_False); + if (Base.IsNull()) + { + Base = DBRep::Get(a[i], TopAbs_FACE, Standard_False); + IsAFace = Standard_True; + } + } + break; + + case 'p': + { + Prof = TopoDS::Wire(DBRep::Get(a[++i], TopAbs_WIRE, Standard_False)); + } + break; + + case 'v': + { + isVolume = Standard_True; + } + break; + + case 'a': + { + hasToComputeAxes = Standard_True; + } + break; + + case 't': + { + aTolerance = Draw::Atof(a[++i]); + } + break; + + default: + di << "Error: Unknown option!\n"; + break; + } } - else { - TopoDS_Shape Volevo - = BRepOffsetAPI_MakeEvolved(TopoDS::Wire(Base),Prof,GeomAbs_Arc,n == 4,Solid); - DBRep::Set(a[1],Volevo); + + if (Base.IsNull() || Prof.IsNull()) + { + di << "Error: Null-shapes are not allowed\n"; + return 1; } + TopoDS_Shape Volevo = IsAFace ? BRepOffsetAPI_MakeEvolved(TopoDS::Face(Base), + Prof, GeomAbs_Arc, !hasToComputeAxes, + Solid, Standard_False, isVolume, + aTolerance, isParallel) : + BRepOffsetAPI_MakeEvolved(TopoDS::Wire(Base), + Prof, GeomAbs_Arc, !hasToComputeAxes, + Solid, Standard_False, isVolume, + aTolerance, isParallel); + + DBRep::Set(a[1],Volevo); + return 0; } @@ -785,7 +845,11 @@ static Standard_Integer buildsweep(Draw_Interpretor& di, Sweep->SetTransitionMode(Transition); } // Reading solid ? - if ((n>cur) && (!strcmp(a[cur],"-S")) ) mksolid = Standard_True; + if ((n > cur) && (!strcmp(a[cur], "-S"))) + { + mksolid = Standard_True; + ++cur; + } // Calcul le resultat Sweep->Build(); @@ -979,10 +1043,6 @@ void BRepTest::SweepCommands(Draw_Interpretor& theCommands) "evolved , no args to get help", __FILE__,evolved,g); - theCommands.Add("evolvedsolid", - "evolved , no args to get help", - __FILE__,evolved,g); - theCommands.Add("pruled", "pruled result Edge1/Wire1 Edge2/Wire2", __FILE__,pruled,g); diff --git a/src/BRepTest/QABugs_20.cxx b/src/BRepTest/QABugs_20.cxx new file mode 100644 index 0000000000..1ff98e2824 --- /dev/null +++ b/src/BRepTest/QABugs_20.cxx @@ -0,0 +1,2705 @@ +// Created on: 2015-10-26 +// Created by: Nikolai BUKHALOV +// Copyright (c) 2002-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#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 + +#pragma comment(lib, "TKCAF.lib") +#pragma comment(lib, "TKCDF.lib") +#pragma comment(lib, "TKLCAF.lib") +#pragma comment(lib, "TKXCAF.lib") +#pragma comment(lib, "TKDCAF.lib") + +//======================================================================= +//function : SurfaceGenOCC26675_1 +//purpose : Generates a surface for intersect (in corresponding +// test case). If we save these surfaces to the disk +// then bug will not be reproduced. Therefore, this generator +// is very important (despite its taking many lines of the code). +//======================================================================= +static Standard_Integer SurfaceGenOCC26675_1( Draw_Interpretor& theDI, + Standard_Integer theNArg, + const char ** theArgVal) +{ + + if(theNArg < 2) + { + theDI << "Use OCC26675_1 result\n"; + return 1; + } + + const gp_Pnt aCircCenter(-112.93397037070100000000, +177.52792379072199000000, +10.63374076104853900000); + const gp_Dir aCircN(+0.00000000000000000000, +1.00000000000000000000, +0.00000000000000000000); + const gp_Dir aCircX(+0.00000000000000000000, -0.00000000000000000000, +1.00000000000000000000); + const gp_Dir anExtrDir(-500.00000000000000000000, -866.02540378443609000000, +0.00000000000000000000); + const gp_Ax2 aCircAxes(aCircCenter, aCircN, aCircX); + const Handle(Geom_Curve) aCurv = new Geom_Circle(aCircAxes, +50.00000000000000000000); + + const Handle(Geom_Surface) aS2 = new Geom_SurfaceOfLinearExtrusion(aCurv, anExtrDir); + + TColgp_Array2OfPnt aPoles(1, 7, 1, 81); + TColStd_Array2OfReal aWeights(1, 7, 1, 81); + TColStd_Array1OfReal aUKnots(1, 2), aVKnots(1, 12); + TColStd_Array1OfInteger aUMult(1, 2), aVMult(1, 12); + const Standard_Integer aUDegree = 6, aVDegree = 8; + + aUKnots(1) = +0.00000000000000000000; + aUKnots(2) = +1.00000000000000000000; + aVKnots(1) = +0.08911853946147080300; + aVKnots(2) = +0.11779167587451674000; + aVKnots(3) = +0.14583467562325506000; + aVKnots(4) = +0.20255081178503931000; + aVKnots(5) = +0.25926694794682359000; + aVKnots(6) = +0.31598308410860781000; + aVKnots(7) = +0.34262437462234741000; + aVKnots(8) = +0.37067364397889985000; + aVKnots(9) = +0.39731552779654306000; + aVKnots(10) = +0.42536420384919182000; + aVKnots(11) = +0.45200329235672548000; + aVKnots(12) = +0.47802918742799144000; + + aUMult(1) = 7; + aUMult(2) = 7; + aVMult(1) = 9; + aVMult(2) = 7; + aVMult(3) = 7; + aVMult(4) = 7; + aVMult(5) = 7; + aVMult(6) = 7; + aVMult(7) = 7; + aVMult(8) = 7; + aVMult(9) = 7; + aVMult(10) = 8; + aVMult(11) = 8; + aVMult(12) = 9; + + //// + { + aWeights.ChangeValue(1, 1) = +1.02986327036737910000; + aPoles.ChangeValue(1, 1) = gp_Pnt(+131.75315905495660000000, +2.88570510351864900000, -66.24709307590461500000); + aWeights.ChangeValue(1, 2) = +1.02989244478761060000; + aPoles.ChangeValue(1, 2) = gp_Pnt(+128.70876344053133000000, +2.88791208181246970000, -67.92914281439198000000); + aWeights.ChangeValue(1, 3) = +1.02991676091113950000; + aPoles.ChangeValue(1, 3) = gp_Pnt(+125.64133203841195000000, +2.88975018186799830000, -69.56968825975690200000); + aWeights.ChangeValue(1, 4) = +1.02993613450133650000; + aPoles.ChangeValue(1, 4) = gp_Pnt(+122.55164101294532000000, +2.89121448973680460000, -71.16831921321855200000); + aWeights.ChangeValue(1, 5) = +1.02995970896170810000; + aPoles.ChangeValue(1, 5) = gp_Pnt(+119.44028474076808000000, +2.89299532863950050000, -72.72471137484106400000); + aWeights.ChangeValue(1, 6) = +1.02998196300928410000; + aPoles.ChangeValue(1, 6) = gp_Pnt(+116.30796917345266000000, +2.89467567823625730000, -74.23853925439507900000); + aWeights.ChangeValue(1, 7) = +1.02999781361772440000; + aPoles.ChangeValue(1, 7) = gp_Pnt(+113.15537818476763000000, +2.89587201010380560000, -75.70949847615843000000); + aWeights.ChangeValue(1, 8) = +1.03001626830283270000; + aPoles.ChangeValue(1, 8) = gp_Pnt(+109.98323502828077000000, +2.89726468512897210000, -77.13723994508107800000); + aWeights.ChangeValue(1, 9) = +1.03004822145815230000; + aPoles.ChangeValue(1, 9) = gp_Pnt(+103.60126699909762000000, +2.89967510685080440000, -79.90571269046952800000); + aWeights.ChangeValue(1, 10) = +1.03006364818936770000; + aPoles.ChangeValue(1, 10) = gp_Pnt(+100.39144092265354000000, +2.90083845616186050000, -81.24644132200651800000); + aWeights.ChangeValue(1, 11) = +1.03007725635592000000; + aPoles.ChangeValue(1, 11) = gp_Pnt(+97.16342330855667300000, +2.90186436688425700000, -82.54338871675531700000); + aWeights.ChangeValue(1, 12) = +1.03009045031501500000; + aPoles.ChangeValue(1, 12) = gp_Pnt(+93.91790293022438600000, +2.90285879918974650000, -83.79626764915399000000); + aWeights.ChangeValue(1, 13) = +1.03010285398183930000; + aPoles.ChangeValue(1, 13) = gp_Pnt(+90.65560197798836800000, +2.90379346029782100000, -85.00479786905465600000); + aWeights.ChangeValue(1, 14) = +1.03011393120350900000; + aPoles.ChangeValue(1, 14) = gp_Pnt(+87.37722618415423900000, +2.90462796925060120000, -86.16871841453435400000); + aWeights.ChangeValue(1, 15) = +1.03012484065787050000; + aPoles.ChangeValue(1, 15) = gp_Pnt(+84.08346762829417300000, +2.90544970249433290000, -87.28777941880029800000); + aWeights.ChangeValue(1, 16) = +1.03015471267321200000; + aPoles.ChangeValue(1, 16) = gp_Pnt(+74.15848807058078800000, +2.90769927244280210000, -90.50962423575197100000); + aWeights.ChangeValue(1, 17) = +1.03017194800922400000; + aPoles.ChangeValue(1, 17) = gp_Pnt(+67.48342008926763900000, +2.90899668032978950000, -92.47701903504494700000); + aWeights.ChangeValue(1, 18) = +1.03018680682765670000; + aPoles.ChangeValue(1, 18) = gp_Pnt(+60.75515833606132100000, +2.91011480947056490000, -94.26204121664201800000); + aWeights.ChangeValue(1, 19) = +1.03019958109549670000; + aPoles.ChangeValue(1, 19) = gp_Pnt(+53.97928154760177200000, +2.91107580930771360000, -95.86305268935117900000); + aWeights.ChangeValue(1, 20) = +1.03021050389503350000; + aPoles.ChangeValue(1, 20) = gp_Pnt(+47.16164692132413400000, +2.91189735380426780000, -97.27865560180262600000); + aWeights.ChangeValue(1, 21) = +1.03021974942385830000; + aPoles.ChangeValue(1, 21) = gp_Pnt(+40.30838837608569500000, +2.91259264267907050000, -98.50769317562559000000); + aWeights.ChangeValue(1, 22) = +1.03022743299486370000; + aPoles.ChangeValue(1, 22) = gp_Pnt(+33.42591476110869300000, +2.91317040233699530000, -99.54925039136011800000); + aWeights.ChangeValue(1, 23) = +1.03023979631718900000; + aPoles.ChangeValue(1, 23) = gp_Pnt(+19.61576136171939000000, +2.91409991934468550000, -101.25602945077115000000); + aWeights.ChangeValue(1, 24) = +1.03024450452679140000; + aPoles.ChangeValue(1, 24) = gp_Pnt(+12.68754355991407800000, +2.91445385083459700000, -101.92122234436175000000); + aWeights.ChangeValue(1, 25) = +1.03024781840890120000; + aPoles.ChangeValue(1, 25) = gp_Pnt(+5.74236948737514120000, +2.91470294045230770000, -102.39751844510502000000); + aWeights.ChangeValue(1, 26) = +1.03024979501192000000; + aPoles.ChangeValue(1, 26) = gp_Pnt(-1.21367831605073050000, +2.91485150371151920000, -102.68442590550356000000); + aWeights.ChangeValue(1, 27) = +1.03025046568879790000; + aPoles.ChangeValue(1, 27) = gp_Pnt(-8.17455041611474620000, +2.91490191238154670000, -102.78167594353056000000); + aWeights.ChangeValue(1, 28) = +1.03024983609703540000; + aPoles.ChangeValue(1, 28) = gp_Pnt(-15.13423127055194300000, +2.91485459458572780000, -102.68922293042964000000); + aWeights.ChangeValue(1, 29) = +1.03024788619868260000; + aPoles.ChangeValue(1, 29) = gp_Pnt(-22.08674002008992700000, +2.91470803482494080000, -102.40724441194320000000); + aWeights.ChangeValue(1, 30) = +1.03024126030624540000; + aPoles.ChangeValue(1, 30) = gp_Pnt(-35.96556766132121700000, +2.91420996731856930000, -101.46503408514069000000); + aWeights.ChangeValue(1, 31) = +1.03023657011944230000; + aPoles.ChangeValue(1, 31) = gp_Pnt(-42.89191729472150200000, +2.91385737699769360000, -100.80479886745856000000); + aWeights.ChangeValue(1, 32) = +1.03023047292900880000; + aPoles.ChangeValue(1, 32) = gp_Pnt(-49.79923779841396900000, +2.91339898565004060000, -99.95583114848535900000); + aWeights.ChangeValue(1, 33) = +1.03022290017099550000; + aPoles.ChangeValue(1, 33) = gp_Pnt(-56.68161614207340900000, +2.91282960709223810000, -98.91875138839027700000); + aWeights.ChangeValue(1, 34) = +1.03021374148842180000; + aPoles.ChangeValue(1, 34) = gp_Pnt(-63.53316994906088400000, +2.91214088593828220000, -97.69440448679608800000); + aWeights.ChangeValue(1, 35) = +1.03020284473128080000; + aPoles.ChangeValue(1, 35) = gp_Pnt(-70.34804877511381000000, +2.91132129711663760000, -96.28385939245710300000); + aWeights.ChangeValue(1, 36) = +1.03019001595653580000; + aPoles.ChangeValue(1, 36) = gp_Pnt(-77.12043535415037400000, +2.91035614521427500000, -94.68840860671046800000); + aWeights.ChangeValue(1, 37) = +1.03016805964614980000; + aPoles.ChangeValue(1, 37) = gp_Pnt(-86.96652166958519100000, +2.90870378328618400000, -92.08365976972685000000); + aWeights.ChangeValue(1, 38) = +1.03016062145972500000; + aPoles.ChangeValue(1, 38) = gp_Pnt(-90.07809790629383400000, +2.90814392820824040000, -91.21821667329717800000); + aWeights.ChangeValue(1, 39) = +1.03015268516758060000; + aPoles.ChangeValue(1, 39) = gp_Pnt(-93.17869710255469300000, +2.90754650188789080000, -90.31338955501080100000); + aWeights.ChangeValue(1, 40) = +1.03014422393874510000; + aPoles.ChangeValue(1, 40) = gp_Pnt(-96.26774201507643600000, +2.90690946644790090000, -89.36934028436292000000); + aWeights.ChangeValue(1, 41) = +1.03013520381253840000; + aPoles.ChangeValue(1, 41) = gp_Pnt(-99.34465666946248100000, +2.90623024256504880000, -88.38624129906430900000); + aWeights.ChangeValue(1, 42) = +1.03012558369857450000; + aPoles.ChangeValue(1, 42) = gp_Pnt(-102.40886646020824000000, +2.90550570939860810000, -87.36427556081821400000); + aWeights.ChangeValue(1, 43) = +1.03011531537676040000; + aPoles.ChangeValue(1, 43) = gp_Pnt(-105.45979824903711000000, +2.90473220450791560000, -86.30363650725728100000); + aWeights.ChangeValue(1, 44) = +1.03009266486593140000; + aPoles.ChangeValue(1, 44) = gp_Pnt(-111.76765655411073000000, +2.90302557752729130000, -84.02084620865503000000); + aWeights.ChangeValue(1, 45) = +1.03007954250893910000; + aPoles.ChangeValue(1, 45) = gp_Pnt(-115.02237879255169000000, +2.90203661863772000000, -82.79254553120374300000); + aWeights.ChangeValue(1, 46) = +1.03006700046846360000; + aPoles.ChangeValue(1, 46) = gp_Pnt(-118.26033551796380000000, +2.90109123094133370000, -81.51987347500843800000); + aWeights.ChangeValue(1, 47) = +1.03005153385518430000; + aPoles.ChangeValue(1, 47) = gp_Pnt(-121.48081153033489000000, +2.89992503429592440000, -80.20310945547186100000); + aWeights.ChangeValue(1, 48) = +1.03003663316288070000; + aPoles.ChangeValue(1, 48) = gp_Pnt(-124.68310204708784000000, +2.89880123910694910000, -78.84252385592422700000); + aWeights.ChangeValue(1, 49) = +1.03002002524051230000; + aPoles.ChangeValue(1, 49) = gp_Pnt(-127.86649232671233000000, +2.89754829341323060000, -77.43842231968982000000); + aWeights.ChangeValue(1, 50) = +1.03000192732161230000; + aPoles.ChangeValue(1, 50) = gp_Pnt(-131.03028254956638000000, +2.89618247462029290000, -75.99111259804850200000); + aWeights.ChangeValue(1, 51) = +1.02996526567113600000; + aPoles.ChangeValue(1, 51) = gp_Pnt(-137.09281139094972000000, +2.89341459629042360000, -73.11712223836046600000); + aWeights.ChangeValue(1, 52) = +1.02994403451589630000; + aPoles.ChangeValue(1, 52) = gp_Pnt(-139.99435839258939000000, +2.89181101472158900000, -71.69634981883045600000); + aWeights.ChangeValue(1, 53) = +1.02992866105538440000; + aPoles.ChangeValue(1, 53) = gp_Pnt(-142.87784656482347000000, +2.89064973421052680000, -70.23882874204873900000); + aWeights.ChangeValue(1, 54) = +1.02989968743283590000; + aPoles.ChangeValue(1, 54) = gp_Pnt(-145.74271824362268000000, +2.88845983550875030000, -68.74489127449217600000); + aWeights.ChangeValue(1, 55) = +1.02988222474524970000; + aPoles.ChangeValue(1, 55) = gp_Pnt(-148.58838121276386000000, +2.88713941077432070000, -67.21475112846350400000); + aWeights.ChangeValue(1, 56) = +1.02985386954408620000; + aPoles.ChangeValue(1, 56) = gp_Pnt(-151.41432118416620000000, +2.88499463682574180000, -65.64875099202183200000); + aWeights.ChangeValue(1, 57) = +1.02982704006090460000; + aPoles.ChangeValue(1, 57) = gp_Pnt(-154.21993049579214000000, +2.88296397171855910000, -64.04717955157212800000); + aWeights.ChangeValue(1, 58) = +1.02976639514278400000; + aPoles.ChangeValue(1, 58) = gp_Pnt(-160.00375832753414000000, +2.87837140815595260000, -60.64735416015690100000); + aWeights.ChangeValue(1, 59) = +1.02972545417711370000; + aPoles.ChangeValue(1, 59) = gp_Pnt(-162.97914403387477000000, +2.87526824819569480000, -58.84445149944087200000); + aWeights.ChangeValue(1, 60) = +1.02970377642253300000; + aPoles.ChangeValue(1, 60) = gp_Pnt(-165.92810584856278000000, +2.87362619373759860000, -56.99783055334398100000); + aWeights.ChangeValue(1, 61) = +1.02963665582001740000; + aPoles.ChangeValue(1, 61) = gp_Pnt(-168.85438185317770000000, +2.86853152516479340000, -55.11698298198095400000); + aWeights.ChangeValue(1, 62) = +1.02961756328192160000; + aPoles.ChangeValue(1, 62) = gp_Pnt(-171.75125340157436000000, +2.86708271055963240000, -53.19057330425229700000); + aWeights.ChangeValue(1, 63) = +1.02954937293527580000; + aPoles.ChangeValue(1, 63) = gp_Pnt(-174.62251681022158000000, +2.86190007017706360000, -51.22700225930964300000); + aWeights.ChangeValue(1, 64) = +1.02950097342691520000; + aPoles.ChangeValue(1, 64) = gp_Pnt(-177.46620192435449000000, +2.85821732043423180000, -49.22415777229338100000); + aWeights.ChangeValue(1, 65) = +1.02943612532291810000; + aPoles.ChangeValue(1, 65) = gp_Pnt(-180.28206426096281000000, +2.85327724467687100000, -47.18300981722491400000); + aWeights.ChangeValue(1, 66) = +1.02937840445786000000; + aPoles.ChangeValue(1, 66) = gp_Pnt(-182.89713737694305000000, +2.84888100315162470000, -45.28741010449485300000); + aWeights.ChangeValue(1, 67) = +1.02929786839840220000; + aPoles.ChangeValue(1, 67) = gp_Pnt(-185.48808576506855000000, +2.84272935508061810000, -43.35897595091199000000); + aWeights.ChangeValue(1, 68) = +1.02927785532845030000; + aPoles.ChangeValue(1, 68) = gp_Pnt(-188.05509745668041000000, +2.84122612975151250000, -41.39706700987362400000); + aWeights.ChangeValue(1, 69) = +1.02909457173363930000; + aPoles.ChangeValue(1, 69) = gp_Pnt(-190.59634219852757000000, +2.82717082550985440000, -39.40453806610211300000); + aWeights.ChangeValue(1, 70) = +1.02915656102508410000; + aPoles.ChangeValue(1, 70) = gp_Pnt(-193.11296933822229000000, +2.83195841118334000000, -37.37763511391345600000); + aWeights.ChangeValue(1, 71) = +1.02891246603941110000; + aPoles.ChangeValue(1, 71) = gp_Pnt(-195.60305999702362000000, +2.81322479805689340000, -35.32107774203857500000); + aWeights.ChangeValue(1, 72) = +1.02884001996307940000; + aPoles.ChangeValue(1, 72) = gp_Pnt(-198.06589030811097000000, +2.80764438138268390000, -33.23208121127716900000); + aWeights.ChangeValue(1, 73) = +1.02870418206103250000; + aPoles.ChangeValue(1, 73) = gp_Pnt(-200.50111697620073000000, +2.79717360924099090000, -31.11182660391394400000); + aWeights.ChangeValue(1, 74) = +1.02860417892814660000; + aPoles.ChangeValue(1, 74) = gp_Pnt(-202.93720652839650000000, +2.78949733525485710000, -28.99085629216911300000); + aWeights.ChangeValue(1, 75) = +1.02826579045547110000; + aPoles.ChangeValue(1, 75) = gp_Pnt(-205.34394850673777000000, +2.76315604312090550000, -26.83940109433629200000); + aWeights.ChangeValue(1, 76) = +1.02871793966742330000; + aPoles.ChangeValue(1, 76) = gp_Pnt(-207.72575255584553000000, +2.79855565223875710000, -24.65500081264426800000); + aWeights.ChangeValue(1, 77) = +1.02728787827176630000; + aPoles.ChangeValue(1, 77) = gp_Pnt(-210.07706367406874000000, +2.68725363743552850000, -22.43634910730148800000); + aWeights.ChangeValue(1, 78) = +1.02767535385809120000; + aPoles.ChangeValue(1, 78) = gp_Pnt(-212.39605978578481000000, +2.71705476277515070000, -20.20562112100595800000); + aWeights.ChangeValue(1, 79) = +1.02745809923169020000; + aPoles.ChangeValue(1, 79) = gp_Pnt(-214.68098626410506000000, +2.69985190382785320000, -17.91605900374278100000); + aWeights.ChangeValue(1, 80) = +1.02725110106359850000; + aPoles.ChangeValue(1, 80) = gp_Pnt(-216.94385389331507000000, +2.68435107488514250000, -15.61289037092123000000); + aWeights.ChangeValue(1, 81) = +1.02619749797986360000; + aPoles.ChangeValue(1, 81) = gp_Pnt(-219.16685583874414000000, +2.59983520096898510000, -13.28583956380401400000); + aWeights.ChangeValue(2, 1) = +1.00955713824395700000; + aPoles.ChangeValue(2, 1) = gp_Pnt(+131.76756408216349000000, +2.10451717388867540000, -66.27316135719137000000); + aWeights.ChangeValue(2, 2) = +1.00956608612165600000; + aPoles.ChangeValue(2, 2) = gp_Pnt(+128.72252404033563000000, +2.10631182699007670000, -67.95492700832653600000); + aWeights.ChangeValue(2, 3) = +1.00957354292813030000; + aPoles.ChangeValue(2, 3) = gp_Pnt(+125.65455798821807000000, +2.10780700070896730000, -69.59522708152212500000); + aWeights.ChangeValue(2, 4) = +1.00957948395970430000; + aPoles.ChangeValue(2, 4) = gp_Pnt(+122.56436007131990000000, +2.10899819276768510000, -71.19369911011085600000); + aWeights.ChangeValue(2, 5) = +1.00958671248272140000; + aPoles.ChangeValue(2, 5) = gp_Pnt(+119.45249930698063000000, +2.11044722765431250000, -72.74983445837314400000); + aWeights.ChangeValue(2, 6) = +1.00959353559448470000; + aPoles.ChangeValue(2, 6) = gp_Pnt(+116.31971419268339000000, +2.11181476538007030000, -74.26341133748536500000); + aWeights.ChangeValue(2, 7) = +1.00959839503054960000; + aPoles.ChangeValue(2, 7) = gp_Pnt(+113.16673272248508000000, +2.11278857229853930000, -75.73421464457315700000); + aWeights.ChangeValue(2, 8) = +1.00960405269294800000; + aPoles.ChangeValue(2, 8) = gp_Pnt(+109.99417142410560000000, +2.11392227976110990000, -77.16175403351917300000); + aWeights.ChangeValue(2, 9) = +1.00961384794963970000; + aPoles.ChangeValue(2, 9) = gp_Pnt(+103.61137952541701000000, +2.11588481923337430000, -79.92991318438167500000); + aWeights.ChangeValue(2, 10) = +1.00961857675621050000; + aPoles.ChangeValue(2, 10) = gp_Pnt(+100.40113044627800000000, +2.11683214779396200000, -81.27049552555527600000); + aWeights.ChangeValue(2, 11) = +1.00962274789480260000; + aPoles.ChangeValue(2, 11) = gp_Pnt(+97.17272090352022900000, +2.11766766635255620000, -82.56731642507010300000); + aWeights.ChangeValue(2, 12) = +1.00962679188946770000; + aPoles.ChangeValue(2, 12) = gp_Pnt(+93.92682593436140300000, +2.11847763961438810000, -83.82006598438695700000); + aWeights.ChangeValue(2, 13) = +1.00963059350869510000; + aPoles.ChangeValue(2, 13) = gp_Pnt(+90.66416580726762200000, +2.11923900414192050000, -85.02847304317147300000); + aWeights.ChangeValue(2, 14) = +1.00963398843777610000; + aPoles.ChangeValue(2, 14) = gp_Pnt(+87.38545325411524800000, +2.11991885797243330000, -86.19228543784532800000); + aWeights.ChangeValue(2, 15) = +1.00963733185346640000; + aPoles.ChangeValue(2, 15) = gp_Pnt(+84.09136475788710600000, +2.12058835416503610000, -87.31123582184922300000); + aWeights.ChangeValue(2, 16) = +1.00964648640037450000; + aPoles.ChangeValue(2, 16) = gp_Pnt(+74.16530685267888100000, +2.12242134451684360000, -90.53282418399284400000); + aWeights.ChangeValue(2, 17) = +1.00965176794147850000; + aPoles.ChangeValue(2, 17) = gp_Pnt(+67.48955141808187400000, +2.12347869023601370000, -92.50007118315201600000); + aWeights.ChangeValue(2, 18) = +1.00965632094816660000; + aPoles.ChangeValue(2, 18) = gp_Pnt(+60.76066172731987800000, +2.12439006790716880000, -94.28495774595940300000); + aWeights.ChangeValue(2, 19) = +1.00966023501695720000; + aPoles.ChangeValue(2, 19) = gp_Pnt(+53.98420072674593900000, +2.12517346720689600000, -95.88584819516199800000); + aWeights.ChangeValue(2, 20) = +1.00966358166845400000; + aPoles.ChangeValue(2, 20) = gp_Pnt(+47.16601123883578600000, +2.12584324589548320000, -97.30134659055448800000); + aWeights.ChangeValue(2, 21) = +1.00966641434734730000; + aPoles.ChangeValue(2, 21) = gp_Pnt(+40.31221541713015500000, +2.12641013013135180000, -98.53029698991525700000); + aWeights.ChangeValue(2, 22) = +1.00966876842241260000; + aPoles.ChangeValue(2, 22) = gp_Pnt(+33.42921418500849000000, +2.12688121470786750000, -99.57178366381829400000); + aWeights.ChangeValue(2, 23) = +1.00967255617655650000; + aPoles.ChangeValue(2, 23) = gp_Pnt(+19.61796125907087400000, +2.12763915883061920000, -101.27845724558523000000); + aWeights.ChangeValue(2, 24) = +1.00967399859793750000; + aPoles.ChangeValue(2, 24) = gp_Pnt(+12.68919279606528900000, +2.12792777824197280000, -101.94361028295506000000); + aWeights.ChangeValue(2, 25) = +1.00967501382968900000; + aPoles.ChangeValue(2, 25) = gp_Pnt(+5.74348853231593990000, +2.12813091177048630000, -102.41987704106546000000); + aWeights.ChangeValue(2, 26) = +1.00967561936957820000; + aPoles.ChangeValue(2, 26) = gp_Pnt(-1.21307744928976070000, +2.12825206894226590000, -102.70676666240287000000); + aWeights.ChangeValue(2, 27) = +1.00967582483410380000; + aPoles.ChangeValue(2, 27) = gp_Pnt(-8.17446448579617170000, +2.12829317854427910000, -102.80401081431219000000); + aWeights.ChangeValue(2, 28) = +1.00967563195849760000; + aPoles.ChangeValue(2, 28) = gp_Pnt(-15.13466558037753100000, +2.12825458864942170000, -102.71156371647888000000); + aWeights.ChangeValue(2, 29) = +1.00967503459672270000; + aPoles.ChangeValue(2, 29) = gp_Pnt(-22.08770764998126900000, +2.12813506662251010000, -102.42960214757312000000); + aWeights.ChangeValue(2, 30) = +1.00967300468446490000; + aPoles.ChangeValue(2, 30) = gp_Pnt(-35.96760988752987500000, +2.12772890088942160000, -101.48744752427969000000); + aWeights.ChangeValue(2, 31) = +1.00967156777535580000; + aPoles.ChangeValue(2, 31) = gp_Pnt(-42.89448004815705000000, +2.12744138030294440000, -100.82725372327035000000); + aWeights.ChangeValue(2, 32) = +1.00966969979090780000; + aPoles.ChangeValue(2, 32) = gp_Pnt(-49.80232400744441900000, +2.12706759457740000000, -99.97834162579670200000); + aWeights.ChangeValue(2, 33) = +1.00966737970297200000; + aPoles.ChangeValue(2, 33) = gp_Pnt(-56.68523628384353000000, +2.12660332632729520000, -98.94133225857957800000); + aWeights.ChangeValue(2, 34) = +1.00966457365849260000; + aPoles.ChangeValue(2, 34) = gp_Pnt(-63.53734456971785200000, +2.12604178346724470000, -97.71706998895581400000); + aWeights.ChangeValue(2, 35) = +1.00966123497950600000; + aPoles.ChangeValue(2, 35) = gp_Pnt(-70.35281013187348300000, +2.12537359908900880000, -96.30662240267085400000); + aWeights.ChangeValue(2, 36) = +1.00965730416314050000; + aPoles.ChangeValue(2, 36) = gp_Pnt(-77.12582820180557500000, +2.12458683129447450000, -94.71128014840769500000); + aWeights.ChangeValue(2, 37) = +1.00965057624220010000; + aPoles.ChangeValue(2, 37) = gp_Pnt(-86.97287762202962800000, +2.12324005462031540000, -92.10671540000876700000); + aWeights.ChangeValue(2, 38) = +1.00964829695753690000; + aPoles.ChangeValue(2, 38) = gp_Pnt(-90.08473551349412400000, +2.12278376932639290000, -91.24134329153459100000); + aWeights.ChangeValue(2, 39) = +1.00964586498084840000; + aPoles.ChangeValue(2, 39) = gp_Pnt(-93.18562459494498300000, +2.12229689243319890000, -90.33659169532975900000); + aWeights.ChangeValue(2, 40) = +1.00964327207694590000; + aPoles.ChangeValue(2, 40) = gp_Pnt(-96.27496896689456200000, +2.12177776971417840000, -89.39262240039663300000); + aWeights.ChangeValue(2, 41) = +1.00964050782222770000; + aPoles.ChangeValue(2, 41) = gp_Pnt(-99.35219429474524600000, +2.12122430736176200000, -88.40960770124299000000); + aWeights.ChangeValue(2, 42) = +1.00963755960468140000; + aPoles.ChangeValue(2, 42) = gp_Pnt(-102.41672784011750000000, +2.12063397196916760000, -87.38773038403248000000); + aWeights.ChangeValue(2, 43) = +1.00963441262388320000; + aPoles.ChangeValue(2, 43) = gp_Pnt(-105.46799849165807000000, +2.12000379050942020000, -86.32718371153289600000); + aWeights.ChangeValue(2, 44) = +1.00962747055142050000; + aPoles.ChangeValue(2, 44) = gp_Pnt(-111.77654530973133000000, +2.11861352771318150000, -84.04460889409097000000); + aWeights.ChangeValue(2, 45) = +1.00962344856326270000; + aPoles.ChangeValue(2, 45) = gp_Pnt(-115.03162075269803000000, +2.11780798556167320000, -82.81644583890866300000); + aWeights.ChangeValue(2, 46) = +1.00961960432211730000; + aPoles.ChangeValue(2, 46) = gp_Pnt(-118.26993104545312000000, +2.11703799459344700000, -81.54389579486141300000); + aWeights.ChangeValue(2, 47) = +1.00961486342011010000; + aPoles.ChangeValue(2, 47) = gp_Pnt(-121.49080060905077000000, +2.11608829135299810000, -80.22729418526657200000); + aWeights.ChangeValue(2, 48) = +1.00961029578343630000; + aPoles.ChangeValue(2, 48) = gp_Pnt(-124.69348951442340000000, +2.11517321690879800000, -78.86685283462101400000); + aWeights.ChangeValue(2, 49) = +1.00960520454014850000; + aPoles.ChangeValue(2, 49) = gp_Pnt(-127.87731027004676000000, +2.11415312105035590000, -77.46291256687052900000); + aWeights.ChangeValue(2, 50) = +1.00959965618773250000; + aPoles.ChangeValue(2, 50) = gp_Pnt(-131.04156234039974000000, +2.11304129636208420000, -76.01577573259778800000); + aWeights.ChangeValue(2, 51) = +1.00958841592243690000; + aPoles.ChangeValue(2, 51) = gp_Pnt(-137.10496896782513000000, +2.11078854745601690000, -73.14215015354327000000); + aWeights.ChangeValue(2, 52) = +1.00958190609540830000; + aPoles.ChangeValue(2, 52) = gp_Pnt(-140.00695092509352000000, +2.10948365684345340000, -71.72161996530125800000); + aWeights.ChangeValue(2, 53) = +1.00957719225994170000; + aPoles.ChangeValue(2, 53) = gp_Pnt(-142.89082065884315000000, +2.10853873486620720000, -70.26423921243410600000); + aWeights.ChangeValue(2, 54) = +1.00956830737110970000; + aPoles.ChangeValue(2, 54) = gp_Pnt(-145.75622246387837000000, +2.10675729535240960000, -68.77065477701791000000); + aWeights.ChangeValue(2, 55) = +1.00956295195561060000; + aPoles.ChangeValue(2, 55) = gp_Pnt(-148.60233584192389000000, +2.10568335609513650000, -67.24065593702246700000); + aWeights.ChangeValue(2, 56) = +1.00955425555818930000; + aPoles.ChangeValue(2, 56) = gp_Pnt(-151.42883073983140000000, +2.10393921590561070000, -65.67497260857376800000); + aWeights.ChangeValue(2, 57) = +1.00954602613011150000; + aPoles.ChangeValue(2, 57) = gp_Pnt(-154.23502547473331000000, +2.10228833319884910000, -64.07366145615235100000); + aWeights.ChangeValue(2, 58) = +1.00952742278729300000; + aPoles.ChangeValue(2, 58) = gp_Pnt(-160.02004322449872000000, +2.09855561509982950000, -60.67448614970191300000); + aWeights.ChangeValue(2, 59) = +1.00951486183164940000; + aPoles.ChangeValue(2, 59) = gp_Pnt(-162.99613088380306000000, +2.09603444654779600000, -58.87207545484513800000); + aWeights.ChangeValue(2, 60) = +1.00950821186194630000; + aPoles.ChangeValue(2, 60) = gp_Pnt(-165.94554723216726000000, +2.09470002788322150000, -57.02566663092176900000); + aWeights.ChangeValue(2, 61) = +1.00948761363819010000; + aPoles.ChangeValue(2, 61) = gp_Pnt(-168.87287521283019000000, +2.09056345777511910000, -55.14566924440539700000); + aWeights.ChangeValue(2, 62) = +1.00948175483840210000; + aPoles.ChangeValue(2, 62) = gp_Pnt(-171.77025983587509000000, +2.08938700649796160000, -53.21936605947655600000); + aWeights.ChangeValue(2, 63) = +1.00946082358399410000; + aPoles.ChangeValue(2, 63) = gp_Pnt(-174.64262250370552000000, +2.08518149324171190000, -51.25662423685646700000); + aWeights.ChangeValue(2, 64) = +1.00944596410269540000; + aPoles.ChangeValue(2, 64) = gp_Pnt(-177.48726621628353000000, +2.08219461660139650000, -49.25423871740036900000); + aWeights.ChangeValue(2, 65) = +1.00942605045267530000; + aPoles.ChangeValue(2, 65) = gp_Pnt(-180.30433731845508000000, +2.07819005191471670000, -47.21374002625280800000); + aWeights.ChangeValue(2, 66) = +1.00940832657289500000; + aPoles.ChangeValue(2, 66) = gp_Pnt(-182.92026834009920000000, +2.07462614892136180000, -45.31887901738367200000); + aWeights.ChangeValue(2, 67) = +1.00938358350026620000; + aPoles.ChangeValue(2, 67) = gp_Pnt(-185.51252638985017000000, +2.06964535925843180000, -43.39137009339865600000); + aWeights.ChangeValue(2, 68) = +1.00937745534293180000; + aPoles.ChangeValue(2, 68) = gp_Pnt(-188.07970214515959000000, +2.06841969296490240000, -41.42984981640538000000); + aWeights.ChangeValue(2, 69) = +1.00932110415642830000; + aPoles.ChangeValue(2, 69) = gp_Pnt(-190.62397551723822000000, +2.05705915800362950000, -39.43932945784815300000); + aWeights.ChangeValue(2, 70) = +1.00934018958961060000; + aPoles.ChangeValue(2, 70) = gp_Pnt(-193.13969442040633000000, +2.06091733419064350000, -37.41169132931209200000); + aWeights.ChangeValue(2, 71) = +1.00926513417552190000; + aPoles.ChangeValue(2, 71) = gp_Pnt(-195.63329272671066000000, +2.04578165519120160000, -35.35822241980492500000); + aWeights.ChangeValue(2, 72) = +1.00924284324010150000; + aPoles.ChangeValue(2, 72) = gp_Pnt(-198.09761820165846000000, +2.04128022217386820000, -33.26975126412686700000); + aWeights.ChangeValue(2, 73) = +1.00920104311988150000; + aPoles.ChangeValue(2, 73) = gp_Pnt(-200.53514329838038000000, +2.03283693524956680000, -31.15087616958502200000); + aWeights.ChangeValue(2, 74) = +1.00917029694372660000; + aPoles.ChangeValue(2, 74) = gp_Pnt(-202.97255799662608000000, +2.02663657044316060000, -29.03126127135719200000); + aWeights.ChangeValue(2, 75) = +1.00906597799637380000; + aPoles.ChangeValue(2, 75) = gp_Pnt(-205.38430250588374000000, +2.00548607046822540000, -26.88375382824776200000); + aWeights.ChangeValue(2, 76) = +1.00920552993214340000; + aPoles.ChangeValue(2, 76) = gp_Pnt(-207.76049754988114000000, +2.03384304897263670000, -24.69318019977189100000); + aWeights.ChangeValue(2, 77) = +1.00876475817298510000; + aPoles.ChangeValue(2, 77) = gp_Pnt(-210.12674832523484000000, +1.94448851661030540000, -22.49703905023471500000); + aWeights.ChangeValue(2, 78) = +1.00888387250469380000; + aPoles.ChangeValue(2, 78) = gp_Pnt(-212.44800842772909000000, +1.96852329008748410000, -20.25405344977475500000); + aWeights.ChangeValue(2, 79) = +1.00881670070680670000; + aPoles.ChangeValue(2, 79) = gp_Pnt(-214.73260668420895000000, +1.95481624964232450000, -17.97008076073228700000); + aWeights.ChangeValue(2, 80) = +1.00875338528797620000; + aPoles.ChangeValue(2, 80) = gp_Pnt(-216.99878954601004000000, +1.94217039944868790000, -15.66960286452947800000); + aWeights.ChangeValue(2, 81) = +1.00842683370719490000; + aPoles.ChangeValue(2, 81) = gp_Pnt(-219.23765241170187000000, +1.87520469423183880000, -13.35291936652889800000); + aWeights.ChangeValue(3, 1) = +0.99802424639217791000; + aPoles.ChangeValue(3, 1) = gp_Pnt(+131.89876890515018000000, +1.35189067474276530000, -66.51059820355672500000); + aWeights.ChangeValue(3, 2) = +0.99802234515929278000; + aPoles.ChangeValue(3, 2) = gp_Pnt(+128.85071311608803000000, +1.35313353595059940000, -68.19368716153405800000); + aWeights.ChangeValue(3, 3) = +0.99802076064203826000; + aPoles.ChangeValue(3, 3) = gp_Pnt(+125.77977143028471000000, +1.35416922698475650000, -69.83529373030198400000); + aWeights.ChangeValue(3, 4) = +0.99801949820651126000; + aPoles.ChangeValue(3, 4) = gp_Pnt(+122.68659332837821000000, +1.35499438550965670000, -71.43508181423516100000); + aWeights.ChangeValue(3, 5) = +0.99801796211084914000; + aPoles.ChangeValue(3, 5) = gp_Pnt(+119.57173533591266000000, +1.35599832254451200000, -72.99244308799212900000); + aWeights.ChangeValue(3, 6) = +0.99801651211145281000; + aPoles.ChangeValue(3, 6) = gp_Pnt(+116.43595392098000000000, +1.35694592285710100000, -74.50721127326711700000); + aWeights.ChangeValue(3, 7) = +0.99801547938002733000; + aPoles.ChangeValue(3, 7) = gp_Pnt(+113.28000153804584000000, +1.35762078417993900000, -75.97921900496575600000); + aWeights.ChangeValue(3, 8) = +0.99801427699595313000; + aPoles.ChangeValue(3, 8) = gp_Pnt(+110.10443724854701000000, +1.35840649430771500000, -77.40790012997213400000); + aWeights.ChangeValue(3, 9) = +0.99801219521191387000; + aPoles.ChangeValue(3, 9) = gp_Pnt(+103.71561277285424000000, +1.35976677896647580000, -80.17831514578958300000); + aWeights.ChangeValue(3, 10) = +0.99801119017200446000; + aPoles.ChangeValue(3, 10) = gp_Pnt(+100.50232486897988000000, +1.36042346207845170000, -81.51999289835789900000); + aWeights.ChangeValue(3, 11) = +0.99801030363459775000; + aPoles.ChangeValue(3, 11) = gp_Pnt(+97.27087733082035500000, +1.36100269005924380000, -82.81788136334564900000); + aWeights.ChangeValue(3, 12) = +0.99800944410125381000; + aPoles.ChangeValue(3, 12) = gp_Pnt(+94.02193936655145000000, +1.36156425167614130000, -84.07165794609035500000); + aWeights.ChangeValue(3, 13) = +0.99800863606857426000; + aPoles.ChangeValue(3, 13) = gp_Pnt(+90.75622955795523700000, +1.36209214789795310000, -85.28105659074749700000); + aWeights.ChangeValue(3, 14) = +0.99800791446328430000; + aPoles.ChangeValue(3, 14) = gp_Pnt(+87.47446474935537700000, +1.36256356235759690000, -86.44582972368263500000); + aWeights.ChangeValue(3, 15) = +0.99800720379689600000; + aPoles.ChangeValue(3, 15) = gp_Pnt(+84.17731596959211500000, +1.36302781837419680000, -87.56569962027794000000); + aWeights.ChangeValue(3, 16) = +0.99800525790220496000; + aPoles.ChangeValue(3, 16) = gp_Pnt(+74.24198734063921300000, +1.36429897306986340000, -90.78996991844945800000); + aWeights.ChangeValue(3, 17) = +0.99800413521623321000; + aPoles.ChangeValue(3, 17) = gp_Pnt(+67.56001809965197000000, +1.36503231983535440000, -92.75885901427626800000); + aWeights.ChangeValue(3, 18) = +0.99800316736440942000; + aPoles.ChangeValue(3, 18) = gp_Pnt(+60.82490109578901600000, +1.36566449260567850000, -94.54523441794054900000); + aWeights.ChangeValue(3, 19) = +0.99800233531441818000; + aPoles.ChangeValue(3, 19) = gp_Pnt(+54.04219505707111900000, +1.36620793936844790000, -96.14746061467829500000); + aWeights.ChangeValue(3, 20) = +0.99800162387306934000; + aPoles.ChangeValue(3, 20) = gp_Pnt(+47.21773986109732800000, +1.36667259642912180000, -97.56414160157402200000); + aWeights.ChangeValue(3, 21) = +0.99800102168630012000; + aPoles.ChangeValue(3, 21) = gp_Pnt(+40.35765665228271400000, +1.36706588836418840000, -98.79412083143951400000); + aWeights.ChangeValue(3, 22) = +0.99800052123917371000; + aPoles.ChangeValue(3, 22) = gp_Pnt(+33.46834796257081700000, +1.36739272798589770000, -99.83648116661171900000); + aWeights.ChangeValue(3, 23) = +0.99799971600020576000; + aPoles.ChangeValue(3, 23) = gp_Pnt(+19.64441706716387900000, +1.36791861440644060000, -101.54459131896159000000); + aWeights.ChangeValue(3, 24) = +0.99799940935225717000; + aPoles.ChangeValue(3, 24) = gp_Pnt(+12.70928858254282900000, +1.36811887624638580000, -102.21030492597274000000); + aWeights.ChangeValue(3, 25) = +0.99799919351964705000; + aPoles.ChangeValue(3, 25) = gp_Pnt(+5.75722078489831280000, +1.36825982711689180000, -102.68697252648171000000); + aWeights.ChangeValue(3, 26) = +0.99799906478455291000; + aPoles.ChangeValue(3, 26) = gp_Pnt(-1.20571159764999210000, +1.36834389755229970000, -102.97410341218257000000); + aWeights.ChangeValue(3, 27) = +0.99799902110371730000; + aPoles.ChangeValue(3, 27) = gp_Pnt(-8.17346746041202720000, +1.36837242333404090000, -103.07142929357101000000); + aWeights.ChangeValue(3, 28) = +0.99799906210844536000; + aPoles.ChangeValue(3, 28) = gp_Pnt(-15.14003926915473600000, +1.36834564548690430000, -102.97890429403182000000); + aWeights.ChangeValue(3, 29) = +0.99799918910460783000; + aPoles.ChangeValue(3, 29) = gp_Pnt(-22.09945300681867100000, +1.36826271027814080000, -102.69670494840925000000); + aWeights.ChangeValue(3, 30) = +0.99799962065035785000; + aPoles.ChangeValue(3, 30) = gp_Pnt(-35.99208002634647800000, +1.36798088374117890000, -101.75375562004130000000); + aWeights.ChangeValue(3, 31) = +0.99799992612548816000; + aPoles.ChangeValue(3, 31) = gp_Pnt(-42.92529183965938000000, +1.36778138671521220000, -101.09300634269859000000); + aWeights.ChangeValue(3, 32) = +0.99800032324181509000; + aPoles.ChangeValue(3, 32) = gp_Pnt(-49.83946240643516700000, +1.36752203923507090000, -100.24338136864999000000); + aWeights.ChangeValue(3, 33) = +0.99800081646744487000; + aPoles.ChangeValue(3, 33) = gp_Pnt(-56.72868525600537000000, +1.36719992054037180000, -99.20550257416397200000); + aWeights.ChangeValue(3, 34) = +0.99800141299480705000; + aPoles.ChangeValue(3, 34) = gp_Pnt(-63.58708851299418500000, +1.36681032802942060000, -97.98021473616272200000); + aWeights.ChangeValue(3, 35) = +0.99800212274065336000; + aPoles.ChangeValue(3, 35) = gp_Pnt(-70.40883481115771800000, +1.36634677727753220000, -96.56858555851044900000); + aWeights.ChangeValue(3, 36) = +0.99800295834605834000; + aPoles.ChangeValue(3, 36) = gp_Pnt(-77.18812120943384500000, +1.36580100206191160000, -94.97190570545618000000); + aWeights.ChangeValue(3, 37) = +0.99800438851666018000; + aPoles.ChangeValue(3, 37) = gp_Pnt(-87.04430869357409500000, +1.36486684103840930000, -92.36516064771883800000); + aWeights.ChangeValue(3, 38) = +0.99800487302440710000; + aPoles.ChangeValue(3, 38) = gp_Pnt(-90.15904180478642600000, +1.36455036334574700000, -91.49906951050012100000); + aWeights.ChangeValue(3, 39) = +0.99800538998403165000; + aPoles.ChangeValue(3, 39) = gp_Pnt(-93.26280104894121300000, +1.36421268117563340000, -90.59356682763008500000); + aWeights.ChangeValue(3, 40) = +0.99800594114472085000; + aPoles.ChangeValue(3, 40) = gp_Pnt(-96.35501076566437500000, +1.36385265030680070000, -89.64881447076304300000); + aWeights.ChangeValue(3, 41) = +0.99800652872047668000; + aPoles.ChangeValue(3, 41) = gp_Pnt(-99.43509702281136200000, +1.36346882243976730000, -88.66498478868943800000); + aWeights.ChangeValue(3, 42) = +0.99800715539011531000; + aPoles.ChangeValue(3, 42) = gp_Pnt(-102.50248760972849000000, +1.36305944519955100000, -87.64226061031386900000); + aWeights.ChangeValue(3, 43) = +0.99800782429726853000; + aPoles.ChangeValue(3, 43) = gp_Pnt(-105.55661203062589000000, +1.36262246213878830000, -86.58083524789229600000); + aWeights.ChangeValue(3, 44) = +0.99800929984388531000; + aPoles.ChangeValue(3, 44) = gp_Pnt(-111.87105232543304000000, +1.36165848631400000000, -84.29637819122412200000); + aWeights.ChangeValue(3, 45) = +0.99801015470554688000; + aPoles.ChangeValue(3, 45) = gp_Pnt(-115.12916723990907000000, +1.36109998387148300000, -83.06721412498791300000); + aWeights.ChangeValue(3, 46) = +0.99801097177629106000; + aPoles.ChangeValue(3, 46) = gp_Pnt(-118.37050305702043000000, +1.36056615831231790000, -81.79361556056927900000); + aWeights.ChangeValue(3, 47) = +0.99801197939908182000; + aPoles.ChangeValue(3, 47) = gp_Pnt(-121.59440429164877000000, +1.35990780214188640000, -80.47594855348815200000); + aWeights.ChangeValue(3, 48) = +0.99801295017732938000; + aPoles.ChangeValue(3, 48) = gp_Pnt(-124.80011198391350000000, +1.35927349774917520000, -79.11439339164216700000); + aWeights.ChangeValue(3, 49) = +0.99801403220993246000; + aPoles.ChangeValue(3, 49) = gp_Pnt(-127.98695272451793000000, +1.35856646260703170000, -77.70931006235629500000); + aWeights.ChangeValue(3, 50) = +0.99801521135673477000; + aPoles.ChangeValue(3, 50) = gp_Pnt(-131.15422466608416000000, +1.35779592883408770000, -76.26099835790641600000); + aWeights.ChangeValue(3, 51) = +0.99801760008173268000; + aPoles.ChangeValue(3, 51) = gp_Pnt(-137.22341426940562000000, +1.35623488186342090000, -73.38505097675174200000); + aWeights.ChangeValue(3, 52) = +0.99801898347031770000; + aPoles.ChangeValue(3, 52) = gp_Pnt(-140.12817143218851000000, +1.35533077140178190000, -71.96340636458091900000); + aWeights.ChangeValue(3, 53) = +0.99801998518653323000; + aPoles.ChangeValue(3, 53) = gp_Pnt(-143.01477271081365000000, +1.35467609324036100000, -70.50482384325539400000); + aWeights.ChangeValue(3, 54) = +0.99802187318341851000; + aPoles.ChangeValue(3, 54) = gp_Pnt(-145.88296929650440000000, +1.35344206211285110000, -69.01011970904052400000); + aWeights.ChangeValue(3, 55) = +0.99802301113749214000; + aPoles.ChangeValue(3, 55) = gp_Pnt(-148.73181832948791000000, +1.35269822187277230000, -67.47885556090747600000); + aWeights.ChangeValue(3, 56) = +0.99802485896116799000; + aPoles.ChangeValue(3, 56) = gp_Pnt(-151.56108889838526000000, +1.35149030610332030000, -65.91196867904423600000); + aWeights.ChangeValue(3, 57) = +0.99802660746081140000; + aPoles.ChangeValue(3, 57) = gp_Pnt(-154.37005843077941000000, +1.35034719652907540000, -64.30939181125272300000); + aWeights.ChangeValue(3, 58) = +0.99803055992501810000; + aPoles.ChangeValue(3, 58) = gp_Pnt(-160.16078498432634000000, +1.34776300585323040000, -60.90758294114521500000); + aWeights.ChangeValue(3, 59) = +0.99803322842151521000; + aPoles.ChangeValue(3, 59) = gp_Pnt(-163.13986451909619000000, +1.34601805132734250000, -59.10384793755353900000); + aWeights.ChangeValue(3, 60) = +0.99803464125751229000; + aPoles.ChangeValue(3, 60) = gp_Pnt(-166.09208359425281000000, +1.34509430571165490000, -57.25595351707911400000); + aWeights.ChangeValue(3, 61) = +0.99803901668572381000; + aPoles.ChangeValue(3, 61) = gp_Pnt(-169.02259847263389000000, +1.34223252516315280000, -55.37471701865561600000); + aWeights.ChangeValue(3, 62) = +0.99804026123487555000; + aPoles.ChangeValue(3, 62) = gp_Pnt(-171.92274649713781000000, +1.34141857200850120000, -53.44681670722970100000); + aWeights.ChangeValue(3, 63) = +0.99804470691034153000; + aPoles.ChangeValue(3, 63) = gp_Pnt(-174.79824691248783000000, +1.33851025764084610000, -51.48277226031661500000); + aWeights.ChangeValue(3, 64) = +0.99804786265209489000; + aPoles.ChangeValue(3, 64) = gp_Pnt(-177.64589658566118000000, +1.33644541377468110000, -49.47887210970986900000); + aWeights.ChangeValue(3, 65) = +0.99805209132461004000; + aPoles.ChangeValue(3, 65) = gp_Pnt(-180.46609411219177000000, +1.33367801102763010000, -47.43691639460438100000); + aWeights.ChangeValue(3, 66) = +0.99805585511720041000; + aPoles.ChangeValue(3, 66) = gp_Pnt(-183.08478109176986000000, +1.33121501172845690000, -45.54077967192022000000); + aWeights.ChangeValue(3, 67) = +0.99806110806405779000; + aPoles.ChangeValue(3, 67) = gp_Pnt(-185.68001727848417000000, +1.32777577033982250000, -43.61205685047624300000); + aWeights.ChangeValue(3, 68) = +0.99806241123000117000; + aPoles.ChangeValue(3, 68) = gp_Pnt(-188.24953622256075000000, +1.32692526187276720000, -41.64902509374122300000); + aWeights.ChangeValue(3, 69) = +0.99807437025077705000; + aPoles.ChangeValue(3, 69) = gp_Pnt(-190.79766796840426000000, +1.31909012471800140000, -39.65777616520052400000); + aWeights.ChangeValue(3, 70) = +0.99807032269259688000; + aPoles.ChangeValue(3, 70) = gp_Pnt(-193.31511620328166000000, +1.32174544077043810000, -37.62798636408343400000); + aWeights.ChangeValue(3, 71) = +0.99808625039380772000; + aPoles.ChangeValue(3, 71) = gp_Pnt(-195.81278252670535000000, +1.31130937814640340000, -35.57429171163009600000); + aWeights.ChangeValue(3, 72) = +0.99809097922828749000; + aPoles.ChangeValue(3, 72) = gp_Pnt(-198.28008499427182000000, +1.30820906528388470000, -33.48422839734306700000); + aWeights.ChangeValue(3, 73) = +0.99809984631895698000; + aPoles.ChangeValue(3, 73) = gp_Pnt(-200.72099421295775000000, +1.30239515227575060000, -31.36416391357070300000); + aWeights.ChangeValue(3, 74) = +0.99810637147759285000; + aPoles.ChangeValue(3, 74) = gp_Pnt(-203.16127009409345000000, +1.29812048781277520000, -29.24337154392900800000); + aWeights.ChangeValue(3, 75) = +0.99812847998895315000; + aPoles.ChangeValue(3, 75) = gp_Pnt(-205.57777363915829000000, +1.28359951668439790000, -27.09591401257074100000); + aWeights.ChangeValue(3, 76) = +0.99809892249848597000; + aPoles.ChangeValue(3, 76) = gp_Pnt(-207.95321979211485000000, +1.30303533816127510000, -24.90029856221717000000); + aWeights.ChangeValue(3, 77) = +0.99819234539248169000; + aPoles.ChangeValue(3, 77) = gp_Pnt(-210.32920376311637000000, +1.24168994973372330000, -22.71372419603407900000); + aWeights.ChangeValue(3, 78) = +0.99816706733577565000; + aPoles.ChangeValue(3, 78) = gp_Pnt(-212.65404345030839000000, +1.25824740351837460000, -20.46200135460381000000); + aWeights.ChangeValue(3, 79) = +0.99818127776964660000; + aPoles.ChangeValue(3, 79) = gp_Pnt(-214.94032188963598000000, +1.24888524402456480000, -18.17894168737611000000); + aWeights.ChangeValue(3, 80) = +0.99819475509197664000; + aPoles.ChangeValue(3, 80) = gp_Pnt(-217.21049138159862000000, +1.24010538580557930000, -15.87773552075580100000); + aWeights.ChangeValue(3, 81) = +0.99826376750414003000; + aPoles.ChangeValue(3, 81) = gp_Pnt(-219.45963474898130000000, +1.19454909379966280000, -13.56324778739743800000); + aWeights.ChangeValue(4, 1) = +0.99424302042862245000; + aPoles.ChangeValue(4, 1) = gp_Pnt(+132.13618409480023000000, +0.70840889522526063000, -66.94024029007874800000); + aWeights.ChangeValue(4, 2) = +0.99423758610938695000; + aPoles.ChangeValue(4, 2) = gp_Pnt(+129.08297406972278000000, +0.70909252303575865000, -68.62615176496952100000); + aWeights.ChangeValue(4, 3) = +0.99423305718875432000; + aPoles.ChangeValue(4, 3) = gp_Pnt(+126.00685240811242000000, +0.70966228194967051000, -70.27050713058781600000); + aWeights.ChangeValue(4, 4) = +0.99422944886444642000; + aPoles.ChangeValue(4, 4) = gp_Pnt(+122.90845587213282000000, +0.71011623149435366000, -71.87297804945868100000); + aWeights.ChangeValue(4, 5) = +0.99422505844796127000; + aPoles.ChangeValue(4, 5) = gp_Pnt(+119.78834767262531000000, +0.71066859395963999000, -73.43294438704307900000); + aWeights.ChangeValue(4, 6) = +0.99422091417503022000; + aPoles.ChangeValue(4, 6) = gp_Pnt(+116.64728496160824000000, +0.71119000548737488000, -74.95024473036627900000); + aWeights.ChangeValue(4, 7) = +0.99421796254996875000; + aPoles.ChangeValue(4, 7) = gp_Pnt(+113.48602386120655000000, +0.71156137519735096000, -76.42471498016054500000); + aWeights.ChangeValue(4, 8) = +0.99421452605999638000; + aPoles.ChangeValue(4, 8) = gp_Pnt(+110.30511547520040000000, +0.71199375553590705000, -77.85578472764748900000); + aWeights.ChangeValue(4, 9) = +0.99420857626658776000; + aPoles.ChangeValue(4, 9) = gp_Pnt(+103.90553506044348000000, +0.71274238201017392000, -80.63083668700706100000); + aWeights.ChangeValue(4, 10) = +0.99420570386914531000; + aPoles.ChangeValue(4, 10) = gp_Pnt(+100.68683453164211000000, +0.71310380757531833000, -81.97476109354066400000); + aWeights.ChangeValue(4, 11) = +0.99420317017586146000; + aPoles.ChangeValue(4, 11) = gp_Pnt(+97.44994659335081600000, +0.71342262156961334000, -83.27482261755635300000); + aWeights.ChangeValue(4, 12) = +0.99420071368291341000; + aPoles.ChangeValue(4, 12) = gp_Pnt(+94.19554253170841200000, +0.71373172711717636000, -84.53069694549194000000); + aWeights.ChangeValue(4, 13) = +0.99419840439350793000; + aPoles.ChangeValue(4, 13) = gp_Pnt(+90.92433917217061900000, +0.71402231445757036000, -85.74211902365664200000); + aWeights.ChangeValue(4, 14) = +0.99419634212229768000; + aPoles.ChangeValue(4, 14) = gp_Pnt(+87.63705473050230000000, +0.71428182289044062000, -86.90884124933938900000); + aWeights.ChangeValue(4, 15) = +0.99419431112670464000; + aPoles.ChangeValue(4, 15) = gp_Pnt(+84.33436439436984200000, +0.71453739893908408000, -88.03058362353205300000); + aWeights.ChangeValue(4, 16) = +0.99418875003915341000; + aPoles.ChangeValue(4, 16) = gp_Pnt(+74.38231313217285400000, +0.71523720648163680000, -91.26025430410756200000); + aWeights.ChangeValue(4, 17) = +0.99418554160984429000; + aPoles.ChangeValue(4, 17) = gp_Pnt(+67.68910051798944500000, +0.71564096751482986000, -93.23244050128337800000); + aWeights.ChangeValue(4, 18) = +0.99418277570171931000; + aPoles.ChangeValue(4, 18) = gp_Pnt(+60.94265918181897500000, +0.71598904839509359000, -95.02180567308657500000); + aWeights.ChangeValue(4, 19) = +0.99418039790864621000; + aPoles.ChangeValue(4, 19) = gp_Pnt(+54.14855416044807900000, +0.71628829211206946000, -96.62671289123449000000); + aWeights.ChangeValue(4, 20) = +0.99417836479981814000; + aPoles.ChangeValue(4, 20) = gp_Pnt(+47.31263275511362600000, +0.71654416141740851000, -98.04576467050098600000); + aWeights.ChangeValue(4, 21) = +0.99417664391975691000; + aPoles.ChangeValue(4, 21) = gp_Pnt(+40.44102486854357200000, +0.71676073875086976000, -99.27780280738555500000); + aWeights.ChangeValue(4, 22) = +0.99417521378830997000; + aPoles.ChangeValue(4, 22) = gp_Pnt(+33.54014335198198900000, +0.71694072618465221000, -100.32190824729783000000); + aWeights.ChangeValue(4, 23) = +0.99417291266204433000; + aPoles.ChangeValue(4, 23) = gp_Pnt(+19.69298272358705000000, +0.71723033475882103000, -102.03287833894613000000); + aWeights.ChangeValue(4, 24) = +0.99417203636017570000; + aPoles.ChangeValue(4, 24) = gp_Pnt(+12.74619890889187300000, +0.71734062296661449000, -102.69970663658552000000); + aWeights.ChangeValue(4, 25) = +0.99417141958182476000; + aPoles.ChangeValue(4, 25) = gp_Pnt(+5.78245043030823250000, +0.71741824902277995000, -103.17717197796689000000); + aWeights.ChangeValue(4, 26) = +0.99417105170022846000; + aPoles.ChangeValue(4, 26) = gp_Pnt(-1.19217909208406270000, +0.71746454980293017000, -103.46478315098152000000); + aWeights.ChangeValue(4, 27) = +0.99417092687508068000; + aPoles.ChangeValue(4, 27) = gp_Pnt(-8.17163978203099180000, +0.71748026003105458000, -103.56227159755184000000); + aWeights.ChangeValue(4, 28) = +0.99417104405253187000; + aPoles.ChangeValue(4, 28) = gp_Pnt(-15.14991535484593800000, +0.71746551227361877000, -103.46959139663633000000); + aWeights.ChangeValue(4, 29) = +0.99417140696519068000; + aPoles.ChangeValue(4, 29) = gp_Pnt(-22.12102296425817400000, +0.71741983693815459000, -103.18691926012113000000); + aWeights.ChangeValue(4, 30) = +0.99417264018315676000; + aPoles.ChangeValue(4, 30) = gp_Pnt(-36.03699423807252300000, +0.71726462804712465000, -102.24239043165372000000); + aWeights.ChangeValue(4, 31) = +0.99417351313460955000; + aPoles.ChangeValue(4, 31) = gp_Pnt(-42.98185258768797500000, +0.71715476185170723000, -101.58053487832193000000); + aWeights.ChangeValue(4, 32) = +0.99417464796983568000; + aPoles.ChangeValue(4, 32) = gp_Pnt(-49.90763755490115700000, +0.71701193671091712000, -100.72948788576410000000); + aWeights.ChangeValue(4, 33) = +0.99417605745995530000; + aPoles.ChangeValue(4, 33) = gp_Pnt(-56.80843390632649900000, +0.71683454604177377000, -99.68987236817491700000); + aWeights.ChangeValue(4, 34) = +0.99417776216385467000; + aPoles.ChangeValue(4, 34) = gp_Pnt(-63.67836146608049600000, +0.71662000367742562000, -98.46253420440308400000); + aWeights.ChangeValue(4, 35) = +0.99417979042818705000; + aPoles.ChangeValue(4, 35) = gp_Pnt(-70.51157486810592400000, +0.71636474389607163000, -97.04854231351581000000); + aWeights.ChangeValue(4, 36) = +0.99418217838737100000; + aPoles.ChangeValue(4, 36) = gp_Pnt(-77.30226331485057800000, +0.71606422146024096000, -95.44918875092946600000); + aWeights.ChangeValue(4, 37) = +0.99418626551507883000; + aPoles.ChangeValue(4, 37) = gp_Pnt(-87.17503156127875700000, +0.71554987190288122000, -92.83807781738744300000); + aWeights.ChangeValue(4, 38) = +0.99418765014289556000; + aPoles.ChangeValue(4, 38) = gp_Pnt(-90.29499963358738100000, +0.71537562386381059000, -91.97053762881716900000); + aWeights.ChangeValue(4, 39) = +0.99418912751868260000; + aPoles.ChangeValue(4, 39) = gp_Pnt(-93.40397633478176000000, +0.71518970580821706000, -91.06351986664817800000); + aWeights.ChangeValue(4, 40) = +0.99419070264287346000; + aPoles.ChangeValue(4, 40) = gp_Pnt(-96.50138523104767800000, +0.71499148886670094000, -90.11718659777564300000); + aWeights.ChangeValue(4, 41) = +0.99419238184469383000; + aPoles.ChangeValue(4, 41) = gp_Pnt(-99.58665166110419900000, +0.71478017704711161000, -89.13171035602891800000); + aWeights.ChangeValue(4, 42) = +0.99419417278216393000; + aPoles.ChangeValue(4, 42) = gp_Pnt(-102.65920271683186000000, +0.71455480723882170000, -88.10727415073346000000); + aWeights.ChangeValue(4, 43) = +0.99419608444209617000; + aPoles.ChangeValue(4, 43) = gp_Pnt(-105.71846722422283000000, +0.71431424921765596000, -87.04407147601585800000); + aWeights.ChangeValue(4, 44) = +0.99420030141669824000; + aPoles.ChangeValue(4, 44) = gp_Pnt(-112.04353021881408000000, +0.71378360593609291000, -84.75579106017932000000); + aWeights.ChangeValue(4, 45) = +0.99420274455295243000; + aPoles.ChangeValue(4, 45) = gp_Pnt(-115.30712351688430000000, +0.71347617951477893000, -83.52457168950516600000); + aWeights.ChangeValue(4, 46) = +0.99420507969516914000; + aPoles.ChangeValue(4, 46) = gp_Pnt(-118.55391065270935000000, +0.71318234625457844000, -82.24884224143599500000); + aWeights.ChangeValue(4, 47) = +0.99420795946419460000; + aPoles.ChangeValue(4, 47) = gp_Pnt(-121.78323693095153000000, +0.71281998990170370000, -80.92897147787398600000); + aWeights.ChangeValue(4, 48) = +0.99421073394729520000; + aPoles.ChangeValue(4, 48) = gp_Pnt(-124.99434061394447000000, +0.71247088780699119000, -79.56513754354314500000); + aWeights.ChangeValue(4, 49) = +0.99421382643715051000; + aPoles.ChangeValue(4, 49) = gp_Pnt(-128.18654935306802000000, +0.71208178090166396000, -78.15770189412481300000); + aWeights.ChangeValue(4, 50) = +0.99421719652005114000; + aPoles.ChangeValue(4, 50) = gp_Pnt(-131.35915951555538000000, +0.71165775668839981000, -76.70696466864815500000); + aWeights.ChangeValue(4, 51) = +0.99422402375653052000; + aPoles.ChangeValue(4, 51) = gp_Pnt(-137.43857370930490000000, +0.71079877890710363000, -73.82620311743470200000); + aWeights.ChangeValue(4, 52) = +0.99422797768691740000; + aPoles.ChangeValue(4, 52) = gp_Pnt(-140.34822128390073000000, +0.71030132584778982000, -72.40218284379008700000); + aWeights.ChangeValue(4, 53) = +0.99423084075610579000; + aPoles.ChangeValue(4, 53) = gp_Pnt(-143.23968120103163000000, +0.70994112075449667000, -70.94115847846593700000); + aWeights.ChangeValue(4, 54) = +0.99423623706224973000; + aPoles.ChangeValue(4, 54) = gp_Pnt(-146.11271315064005000000, +0.70926223398833632000, -69.44395856663618400000); + aWeights.ChangeValue(4, 55) = +0.99423948964319253000; + aPoles.ChangeValue(4, 55) = gp_Pnt(-148.96636467875118000000, +0.70885305306993507000, -67.91012785943519200000); + aWeights.ChangeValue(4, 56) = +0.99424477127021760000; + aPoles.ChangeValue(4, 56) = gp_Pnt(-151.80041102174371000000, +0.70818863107582075000, -66.34061951491401000000); + aWeights.ChangeValue(4, 57) = +0.99424976912431906000; + aPoles.ChangeValue(4, 57) = gp_Pnt(-154.61412826195317000000, +0.70755993553172780000, -64.73535576374381200000); + aWeights.ChangeValue(4, 58) = +0.99426106692542415000; + aPoles.ChangeValue(4, 58) = gp_Pnt(-160.41462700323274000000, +0.70613881146866808000, -61.32785485541679500000); + aWeights.ChangeValue(4, 59) = +0.99426869485276259000; + aPoles.ChangeValue(4, 59) = gp_Pnt(-163.39874797129167000000, +0.70517937516238605000, -59.52109641918814000000); + aWeights.ChangeValue(4, 60) = +0.99427273335051769000; + aPoles.ChangeValue(4, 60) = gp_Pnt(-166.35588428707737000000, +0.70467140031138198000, -57.67014968010805400000); + aWeights.ChangeValue(4, 61) = +0.99428524121150996000; + aPoles.ChangeValue(4, 61) = gp_Pnt(-169.29147402675417000000, +0.70309833118760823000, -55.78569706052214600000); + aWeights.ChangeValue(4, 62) = +0.99428879891231192000; + aPoles.ChangeValue(4, 62) = gp_Pnt(-172.19641321622018000000, +0.70265088960130029000, -53.85463096447261900000); + aWeights.ChangeValue(4, 63) = +0.99430150819260854000; + aPoles.ChangeValue(4, 63) = gp_Pnt(-175.07684836851479000000, +0.70105264832187786000, -51.88726956537038900000); + aWeights.ChangeValue(4, 64) = +0.99431053021705873000; + aPoles.ChangeValue(4, 64) = gp_Pnt(-177.92932492963632000000, +0.69991818857623234000, -49.88000737868681300000); + aWeights.ChangeValue(4, 65) = +0.99432262020918794000; + aPoles.ChangeValue(4, 65) = gp_Pnt(-180.75433885652521000000, +0.69839807993520564000, -47.83460859504128800000); + aWeights.ChangeValue(4, 66) = +0.99433338093448842000; + aPoles.ChangeValue(4, 66) = gp_Pnt(-183.37745173242254000000, +0.69704510882650861000, -45.93530736698277700000); + aWeights.ChangeValue(4, 67) = +0.99434840096468768000; + aPoles.ChangeValue(4, 67) = gp_Pnt(-185.97711214268182000000, +0.69515696483250133000, -44.00334265992864100000); + aWeights.ChangeValue(4, 68) = +0.99435212441487342000; + aPoles.ChangeValue(4, 68) = gp_Pnt(-188.55092060214918000000, +0.69468843290184534000, -42.03706245316480100000); + aWeights.ChangeValue(4, 69) = +0.99438632495837886000; + aPoles.ChangeValue(4, 69) = gp_Pnt(-191.10351948864678000000, +0.69039032514405918000, -40.04240176159244400000); + aWeights.ChangeValue(4, 70) = +0.99437474610357146000; + aPoles.ChangeValue(4, 70) = gp_Pnt(-193.62512272227769000000, +0.69184483548244469000, -38.00925246210125900000); + aWeights.ChangeValue(4, 71) = +0.99442029730057158000; + aPoles.ChangeValue(4, 71) = gp_Pnt(-196.12715745709386000000, +0.68612074693666814000, -35.95207510226987300000); + aWeights.ChangeValue(4, 72) = +0.99443382321708784000; + aPoles.ChangeValue(4, 72) = gp_Pnt(-198.59871781224271000000, +0.68442148883790921000, -33.85842837168388500000); + aWeights.ChangeValue(4, 73) = +0.99445918644353237000; + aPoles.ChangeValue(4, 73) = gp_Pnt(-201.04387700918369000000, +0.68123533540985159000, -31.73471330438436400000); + aWeights.ChangeValue(4, 74) = +0.99447784672499884000; + aPoles.ChangeValue(4, 74) = gp_Pnt(-203.48830197003542000000, +0.67889067518118906000, -29.61036197082074800000); + aWeights.ChangeValue(4, 75) = +0.99454111417144087000; + aPoles.ChangeValue(4, 75) = gp_Pnt(-205.90905874701556000000, +0.67094847421818948000, -27.45911353863423800000); + aWeights.ChangeValue(4, 76) = +0.99445650432969468000; + aPoles.ChangeValue(4, 76) = gp_Pnt(-208.28851122415659000000, +0.68156618053615436000, -25.25989914496455000000); + aWeights.ChangeValue(4, 77) = +0.99472383917628937000; + aPoles.ChangeValue(4, 77) = gp_Pnt(-210.66819860636727000000, +0.64801004101885640000, -23.06997485052475800000); + aWeights.ChangeValue(4, 78) = +0.99465154011060308000; + aPoles.ChangeValue(4, 78) = gp_Pnt(-212.99829629837927000000, +0.65709020698928045000, -20.81293704958459000000); + aWeights.ChangeValue(4, 79) = +0.99469225299704522000; + aPoles.ChangeValue(4, 79) = gp_Pnt(-215.28778722004142000000, +0.65198647566642243000, -18.52648999480212300000); + aWeights.ChangeValue(4, 80) = +0.99473072608314816000; + aPoles.ChangeValue(4, 80) = gp_Pnt(-217.56233176434088000000, +0.64714607636795729000, -16.22125679272672700000); + aWeights.ChangeValue(4, 81) = +0.99492849872148770000; + aPoles.ChangeValue(4, 81) = gp_Pnt(-219.81591407133737000000, +0.62237708094437050000, -13.90082269618381800000); + aWeights.ChangeValue(5, 1) = +0.99802424639217535000; + aPoles.ChangeValue(5, 1) = gp_Pnt(+132.45622778603641000000, +0.24240580374773624000, -67.51941232824347600000); + aWeights.ChangeValue(5, 2) = +0.99802234515930366000; + aPoles.ChangeValue(5, 2) = gp_Pnt(+129.39621499227619000000, +0.24264599956164210000, -69.20932849809996400000); + aWeights.ChangeValue(5, 3) = +0.99802076064199163000; + aPoles.ChangeValue(5, 3) = gp_Pnt(+126.31320722587012000000, +0.24284620475411531000, -70.85757023346207000000); + aWeights.ChangeValue(5, 4) = +0.99801949820656444000; + aPoles.ChangeValue(5, 4) = gp_Pnt(+123.20785947444472000000, +0.24300571706284735000, -72.46379895615213200000); + aWeights.ChangeValue(5, 5) = +0.99801796211084626000; + aPoles.ChangeValue(5, 5) = gp_Pnt(+120.08075545981777000000, +0.24319982314295371000, -74.02745916652884300000); + aWeights.ChangeValue(5, 6) = +0.99801651211139986000; + aPoles.ChangeValue(5, 6) = gp_Pnt(+116.93263892914923000000, +0.24338306180645181000, -75.54835063375608700000); + aWeights.ChangeValue(5, 7) = +0.99801547938007906000; + aPoles.ChangeValue(5, 7) = gp_Pnt(+113.76425167349765000000, +0.24351357797625062000, -77.02627451676777100000); + aWeights.ChangeValue(5, 8) = +0.99801427699593348000; + aPoles.ChangeValue(5, 8) = gp_Pnt(+110.57618061475338000000, +0.24366553774363486000, -78.46071663606139200000); + aWeights.ChangeValue(5, 9) = +0.99801219521177365000; + aPoles.ChangeValue(5, 9) = gp_Pnt(+104.16217613984874000000, +0.24392865233284403000, -81.24228081548614000000); + aWeights.ChangeValue(5, 10) = +0.99801119017243534000; + aPoles.ChangeValue(5, 10) = gp_Pnt(+100.93622072836907000000, +0.24405568433254640000, -82.58935804874866400000); + aWeights.ChangeValue(5, 11) = +0.99801030363411136000; + aPoles.ChangeValue(5, 11) = gp_Pnt(+97.69202612265307600000, +0.24416774311013159000, -83.89246252379766100000); + aWeights.ChangeValue(5, 12) = +0.99800944410126124000; + aPoles.ChangeValue(5, 12) = gp_Pnt(+94.43027249107268500000, +0.24427639255629080000, -85.15127753548810600000); + aWeights.ChangeValue(5, 13) = +0.99800863606905588000; + aPoles.ChangeValue(5, 13) = gp_Pnt(+91.15167507122404800000, +0.24437853537532742000, -86.36553541507953500000); + aWeights.ChangeValue(5, 14) = +0.99800791446282866000; + aPoles.ChangeValue(5, 14) = gp_Pnt(+87.85695090009397700000, +0.24446975628264125000, -87.53498464352057300000); + aWeights.ChangeValue(5, 15) = +0.99800720379704511000; + aPoles.ChangeValue(5, 15) = gp_Pnt(+84.54678770958248900000, +0.24455959646371978000, -88.65934979276558200000); + aWeights.ChangeValue(5, 16) = +0.99800525790220262000; + aPoles.ChangeValue(5, 16) = gp_Pnt(+74.57222162875666500000, +0.24480559775636487000, -91.89655746079053200000); + aWeights.ChangeValue(5, 17) = +0.99800413521623044000; + aPoles.ChangeValue(5, 17) = gp_Pnt(+67.86385477996348900000, +0.24494753702776123000, -93.87334138726605200000); + aWeights.ChangeValue(5, 18) = +0.99800316736440708000; + aPoles.ChangeValue(5, 18) = gp_Pnt(+61.10212188651380700000, +0.24506990714535715000, -95.66687639706128700000); + aWeights.ChangeValue(5, 19) = +0.99800233531441618000; + aPoles.ChangeValue(5, 19) = gp_Pnt(+54.29260355218377000000, +0.24517511152453569000, -97.27552257290322800000); + aWeights.ChangeValue(5, 20) = +0.99800162387306812000; + aPoles.ChangeValue(5, 20) = gp_Pnt(+47.44116356008504500000, +0.24526506890417449000, -98.69787956398771200000); + aWeights.ChangeValue(5, 21) = +0.99800102168629923000; + aPoles.ChangeValue(5, 21) = gp_Pnt(+40.55394899036769400000, +0.24534121333759545000, -99.93278652962781900000); + aWeights.ChangeValue(5, 22) = +0.99800052123917249000; + aPoles.ChangeValue(5, 22) = gp_Pnt(+33.63739034141031700000, +0.24540449418574758000, -100.97932209286283000000); + aWeights.ChangeValue(5, 23) = +0.99799971600020576000; + aPoles.ChangeValue(5, 23) = gp_Pnt(+19.75877904385457000000, +0.24550631764576064000, -102.69427034587730000000); + aWeights.ChangeValue(5, 24) = +0.99799940935225595000; + aPoles.ChangeValue(5, 24) = gp_Pnt(+12.79621461719473900000, +0.24554509442498113000, -103.36264862290150000000); + aWeights.ChangeValue(5, 25) = +0.99799919351964361000; + aPoles.ChangeValue(5, 25) = gp_Pnt(+5.81664173483571470000, +0.24557238768930081000, -103.84122357926364000000); + aWeights.ChangeValue(5, 26) = +0.99799906478454914000; + aPoles.ChangeValue(5, 26) = gp_Pnt(-1.17384006705611750000, +0.24558866712534574000, -104.12950288114470000000); + aWeights.ChangeValue(5, 27) = +0.99799902110371452000; + aPoles.ChangeValue(5, 27) = gp_Pnt(-8.16916502467035950000, +0.24559419086566145000, -104.22721740658889000000); + aWeights.ChangeValue(5, 28) = +0.99799906210844525000; + aPoles.ChangeValue(5, 28) = gp_Pnt(-15.16330109337111900000, +0.24558900548798951000, -104.13432123956672000000); + aWeights.ChangeValue(5, 29) = +0.99799918910460916000; + aPoles.ChangeValue(5, 29) = gp_Pnt(-22.15024989420349800000, +0.24557294601509544000, -103.85099166853988000000); + aWeights.ChangeValue(5, 30) = +0.99799962065035952000; + aPoles.ChangeValue(5, 30) = gp_Pnt(-36.09784025928350100000, +0.24551837507724711000, -102.90426687944763000000); + aWeights.ChangeValue(5, 31) = +0.99799992612548860000; + aPoles.ChangeValue(5, 31) = gp_Pnt(-43.05848024708384300000, +0.24547974681812620000, -102.24087223758063000000); + aWeights.ChangeValue(5, 32) = +0.99800032324181287000; + aPoles.ChangeValue(5, 32) = gp_Pnt(-50.00000136683811300000, +0.24542953068576923000, -101.38784584473753000000); + aWeights.ChangeValue(5, 33) = +0.99800081646744143000; + aPoles.ChangeValue(5, 33) = gp_Pnt(-56.91647304260395400000, +0.24536716218422927000, -100.34581179308852000000); + aWeights.ChangeValue(5, 34) = +0.99800141299480460000; + aPoles.ChangeValue(5, 34) = gp_Pnt(-63.80199929133657100000, +0.24529173277606747000, -99.11561770524215800000); + aWeights.ChangeValue(5, 35) = +0.99800212274065292000; + aPoles.ChangeValue(5, 35) = gp_Pnt(-70.65071863638867500000, +0.24520198988589620000, -97.69833476064030700000); + aWeights.ChangeValue(5, 36) = +0.99800295834605834000; + aPoles.ChangeValue(5, 36) = gp_Pnt(-77.45680402323041800000, +0.24509633690518939000, -96.09525772913629300000); + aWeights.ChangeValue(5, 37) = +0.99800438851665707000; + aPoles.ChangeValue(5, 37) = gp_Pnt(-87.35194268844766400000, +0.24491551610541196000, -93.47806376363495000000); + aWeights.ChangeValue(5, 38) = +0.99800487302440644000; + aPoles.ChangeValue(5, 38) = gp_Pnt(-90.47898339307414500000, +0.24485425955861742000, -92.60850028621504700000); + aWeights.ChangeValue(5, 39) = +0.99800538998403221000; + aPoles.ChangeValue(5, 39) = gp_Pnt(-93.59500505694055100000, +0.24478890139349116000, -91.69936647202810300000); + aWeights.ChangeValue(5, 40) = +0.99800594114472096000; + aPoles.ChangeValue(5, 40) = gp_Pnt(-96.69942959625443300000, +0.24471922075774133000, -90.75082469114758500000); + aWeights.ChangeValue(5, 41) = +0.99800652872047502000; + aPoles.ChangeValue(5, 41) = gp_Pnt(-99.79168063143930600000, +0.24464493811196314000, -89.76304779373697300000); + aWeights.ChangeValue(5, 42) = +0.99800715539011187000; + aPoles.ChangeValue(5, 42) = gp_Pnt(-102.87118348036965000000, +0.24456571523016235000, -88.73621911304020700000); + aWeights.ChangeValue(5, 43) = +0.99800782429726465000; + aPoles.ChangeValue(5, 43) = gp_Pnt(-105.93736515171811000000, +0.24448115520035879000, -87.67053246863201800000); + aWeights.ChangeValue(5, 44) = +0.99800929984371112000; + aPoles.ChangeValue(5, 44) = gp_Pnt(-112.27672847568951000000, +0.24429462970498794000, -85.37690123862388700000); + aWeights.ChangeValue(5, 45) = +0.99801015470633669000; + aPoles.ChangeValue(5, 45) = gp_Pnt(-115.54769755356581000000, +0.24418656943131900000, -84.14279592325505100000); + aWeights.ChangeValue(5, 46) = +0.99801097177455889000; + aPoles.ChangeValue(5, 46) = gp_Pnt(-118.80182311076892000000, +0.24408328894344730000, -82.86408351153079400000); + aWeights.ChangeValue(5, 47) = +0.99801197940129383000; + aPoles.ChangeValue(5, 47) = gp_Pnt(-122.03843417449148000000, +0.24395592759703674000, -81.54111184389478200000); + aWeights.ChangeValue(5, 48) = +0.99801295017559344000; + aPoles.ChangeValue(5, 48) = gp_Pnt(-125.25678060282321000000, +0.24383322797751039000, -80.17408187890907800000); + aWeights.ChangeValue(5, 49) = +0.99801403221073270000; + aPoles.ChangeValue(5, 49) = gp_Pnt(-128.45617956663568000000, +0.24369647262362162000, -78.76334161483092100000); + aWeights.ChangeValue(5, 50) = +0.99801521135655380000; + aPoles.ChangeValue(5, 50) = gp_Pnt(-131.63592529803751000000, +0.24354745092247693000, -77.30919404502431300000); + aWeights.ChangeValue(5, 51) = +0.99801760008187401000; + aPoles.ChangeValue(5, 51) = gp_Pnt(-137.72900951211963000000, +0.24324557860805471000, -74.42165429070698200000); + aWeights.ChangeValue(5, 52) = +0.99801898346970708000; + aPoles.ChangeValue(5, 52) = gp_Pnt(-140.64518873661288000000, +0.24307076523393223000, -72.99426192178911800000); + aWeights.ChangeValue(5, 53) = +0.99801998518786039000; + aPoles.ChangeValue(5, 53) = gp_Pnt(-143.54316005505726000000, +0.24294418386170585000, -71.52981926220020600000); + aWeights.ChangeValue(5, 54) = +0.99802187318168345000; + aPoles.ChangeValue(5, 54) = gp_Pnt(-146.42260629144496000000, +0.24270562978064991000, -70.02903356238938700000); + aWeights.ChangeValue(5, 55) = +0.99802301113888081000; + aPoles.ChangeValue(5, 55) = gp_Pnt(-149.28266198929455000000, +0.24256185427332766000, -68.49161271016626500000); + aWeights.ChangeValue(5, 56) = +0.99802485896051119000; + aPoles.ChangeValue(5, 56) = gp_Pnt(-152.12302992679020000000, +0.24232840183433180000, -66.91836178765569800000); + aWeights.ChangeValue(5, 57) = +0.99802660746095961000; + aPoles.ChangeValue(5, 57) = gp_Pnt(-154.94301695331424000000, +0.24210751871096883000, -65.30929034698890200000); + aWeights.ChangeValue(5, 58) = +0.99803055992501044000; + aPoles.ChangeValue(5, 58) = gp_Pnt(-160.75642720778953000000, +0.24160825342055195000, -61.89368007550259400000); + aWeights.ChangeValue(5, 59) = +0.99803322842160846000; + aPoles.ChangeValue(5, 59) = gp_Pnt(-163.74717060555361000000, +0.24127121961594802000, -60.08255013672670200000); + aWeights.ChangeValue(5, 60) = +0.99803464125717123000; + aPoles.ChangeValue(5, 60) = gp_Pnt(-166.71086689375946000000, +0.24109275824918924000, -58.22731479955884700000); + aWeights.ChangeValue(5, 61) = +0.99803901668628470000; + aPoles.ChangeValue(5, 61) = gp_Pnt(-169.65297207222594000000, +0.24054025241076704000, -56.33806928337021700000); + aWeights.ChangeValue(5, 62) = +0.99804026123435818000; + aPoles.ChangeValue(5, 62) = gp_Pnt(-172.56427255537395000000, +0.24038308942389072000, -54.40260496408483000000); + aWeights.ChangeValue(5, 63) = +0.99804470691060532000; + aPoles.ChangeValue(5, 63) = gp_Pnt(-175.45101016300779000000, +0.23982181928534163000, -52.43032166263763100000); + aWeights.ChangeValue(5, 64) = +0.99804786265202527000; + aPoles.ChangeValue(5, 64) = gp_Pnt(-178.30970270493245000000, +0.23942347201733374000, -50.41823769283568900000); + aWeights.ChangeValue(5, 65) = +0.99805209132460959000; + aPoles.ChangeValue(5, 65) = gp_Pnt(-181.14080917168710000000, +0.23888978094458979000, -48.36782293133622100000); + aWeights.ChangeValue(5, 66) = +0.99805585511722006000; + aPoles.ChangeValue(5, 66) = gp_Pnt(-183.76963089028271000000, +0.23841474156011525000, -46.46384963887197700000); + aWeights.ChangeValue(5, 67) = +0.99806110806389992000; + aPoles.ChangeValue(5, 67) = gp_Pnt(-186.37480135254410000000, +0.23775204017864099000, -44.52702607060874100000); + aWeights.ChangeValue(5, 68) = +0.99806241123039841000; + aPoles.ChangeValue(5, 68) = gp_Pnt(-188.95443339023049000000, +0.23758721013871806000, -42.55611011320790700000); + aWeights.ChangeValue(5, 69) = +0.99807437025022461000; + aPoles.ChangeValue(5, 69) = gp_Pnt(-191.51185439080101000000, +0.23607937004601673000, -40.55588840407725800000); + aWeights.ChangeValue(5, 70) = +0.99807032269304363000; + aPoles.ChangeValue(5, 70) = gp_Pnt(-194.03956238778505000000, +0.23658914396266717000, -38.51843887702921200000); + aWeights.ChangeValue(5, 71) = +0.99808625039358922000; + aPoles.ChangeValue(5, 71) = gp_Pnt(-196.54607703546344000000, +0.23458111537982981000, -36.45513422497234800000); + aWeights.ChangeValue(5, 72) = +0.99809097922833689000; + aPoles.ChangeValue(5, 72) = gp_Pnt(-199.02284030117690000000, +0.23398526561785285000, -34.35633603568415100000); + aWeights.ChangeValue(5, 73) = +0.99809984631895676000; + aPoles.ChangeValue(5, 73) = gp_Pnt(-201.47284391020807000000, +0.23286808083306546000, -32.22700780168109700000); + aWeights.ChangeValue(5, 74) = +0.99810637147739267000; + aPoles.ChangeValue(5, 74) = gp_Pnt(-203.92239692899503000000, +0.23204542949601353000, -30.09717639714928000000); + aWeights.ChangeValue(5, 75) = +0.99812847998973830000; + aPoles.ChangeValue(5, 75) = gp_Pnt(-206.34684289021220000000, +0.22926391512904498000, -27.93902362306789300000); + aWeights.ChangeValue(5, 76) = +0.99809892249694432000; + aPoles.ChangeValue(5, 76) = gp_Pnt(-208.73420674519565000000, +0.23297935369059405000, -25.73750919512989600000); + aWeights.ChangeValue(5, 77) = +0.99819234539430379000; + aPoles.ChangeValue(5, 77) = gp_Pnt(-211.11258262007470000000, +0.22122441504945897000, -23.53328220960779800000); + aWeights.ChangeValue(5, 78) = +0.99816706733442118000; + aPoles.ChangeValue(5, 78) = gp_Pnt(-213.44890831521380000000, +0.22441150695403267000, -21.27426418813643800000); + aWeights.ChangeValue(5, 79) = +0.99818127777024523000; + aPoles.ChangeValue(5, 79) = gp_Pnt(-215.74298068197336000000, +0.22262736656649654000, -18.98075706196405200000); + aWeights.ChangeValue(5, 80) = +0.99819475509184485000; + aPoles.ChangeValue(5, 80) = gp_Pnt(-218.02209738817496000000, +0.22092240555297402000, -16.66880151580776100000); + aWeights.ChangeValue(5, 81) = +0.99826376750413803000; + aPoles.ChangeValue(5, 81) = gp_Pnt(-220.27506837008727000000, +0.21227676902692139000, -14.33587171753685400000); + aWeights.ChangeValue(6, 1) = +1.00955713824395920000; + aPoles.ChangeValue(6, 1) = gp_Pnt(+132.82497533600920000000, -0.00000000000000355271, -68.18672206105269100000); + aWeights.ChangeValue(6, 2) = +1.00956608612165510000; + aPoles.ChangeValue(6, 2) = gp_Pnt(+129.75720107675980000000, -0.00000000000001501048, -69.88134023490506800000); + aWeights.ChangeValue(6, 3) = +1.00957354292813720000; + aPoles.ChangeValue(6, 3) = gp_Pnt(+126.66630562875893000000, +0.00000000000001468880, -71.53414324810810900000); + aWeights.ChangeValue(6, 4) = +1.00957948395969920000; + aPoles.ChangeValue(6, 4) = gp_Pnt(+123.55299204973852000000, -0.00000000000002420214, -73.14476521965842400000); + aWeights.ChangeValue(6, 5) = +1.00958671248272540000; + aPoles.ChangeValue(6, 5) = gp_Pnt(+120.41786571412476000000, +0.00000000000000774289, -74.71276629883676900000); + aWeights.ChangeValue(6, 6) = +1.00959353559449030000; + aPoles.ChangeValue(6, 6) = gp_Pnt(+117.26165038381876000000, +0.00000000000002827238, -76.23787924846354300000); + aWeights.ChangeValue(6, 7) = +1.00959839503053540000; + aPoles.ChangeValue(6, 7) = gp_Pnt(+114.08506189168672000000, -0.00000000000002567399, -77.71984701658058700000); + aWeights.ChangeValue(6, 8) = +1.00960405269295440000; + aPoles.ChangeValue(6, 8) = gp_Pnt(+110.88875430250306000000, +0.00000000000001531652, -79.15824703626482500000); + aWeights.ChangeValue(6, 9) = +1.00961384794965610000; + aPoles.ChangeValue(6, 9) = gp_Pnt(+104.45816547225203000000, +0.00000000000002372811, -81.94743615023858800000); + aWeights.ChangeValue(6, 10) = +1.00961857675613920000; + aPoles.ChangeValue(6, 10) = gp_Pnt(+101.22387341781818000000, -0.00000000000003253030, -83.29820264563102200000); + aWeights.ChangeValue(6, 11) = +1.00962274789490230000; + aPoles.ChangeValue(6, 11) = gp_Pnt(+97.97127406275538400000, +0.00000000000002165813, -84.60486564781918200000); + aWeights.ChangeValue(6, 12) = +1.00962679188945900000; + aPoles.ChangeValue(6, 12) = gp_Pnt(+94.70106106239124700000, +0.00000000000003307844, -85.86712155505158300000); + aWeights.ChangeValue(6, 13) = +1.00963059350859920000; + aPoles.ChangeValue(6, 13) = gp_Pnt(+91.41394873512904000000, -0.00000000000001002370, -87.08469757155246800000); + aWeights.ChangeValue(6, 14) = +1.00963398843787310000; + aPoles.ChangeValue(6, 14) = gp_Pnt(+88.11065082060795800000, -0.00000000000001620026, -88.25733602781997400000); + aWeights.ChangeValue(6, 15) = +1.00963733185343440000; + aPoles.ChangeValue(6, 15) = gp_Pnt(+84.79187377942922400000, +0.00000000000001387836, -89.38476986722990600000); + aWeights.ChangeValue(6, 16) = +1.00964648640037490000; + aPoles.ChangeValue(6, 16) = gp_Pnt(+74.79138897281484300000, +0.00000000000001147648, -92.63077806554609600000); + aWeights.ChangeValue(6, 17) = +1.00965176794147980000; + aPoles.ChangeValue(6, 17) = gp_Pnt(+68.06556894151637500000, +0.00000000000001348105, -94.61292925638954900000); + aWeights.ChangeValue(6, 18) = +1.00965632094816880000; + aPoles.ChangeValue(6, 18) = gp_Pnt(+61.28620656548358900000, +0.00000000000001132208, -96.41133393799678700000); + aWeights.ChangeValue(6, 19) = +1.00966023501695920000; + aPoles.ChangeValue(6, 19) = gp_Pnt(+54.45890525472331200000, +0.00000000000000779610, -98.02434736777235000000); + aWeights.ChangeValue(6, 20) = +1.00966358166845540000; + aPoles.ChangeValue(6, 20) = gp_Pnt(+47.58955228763309700000, +0.00000000000000496426, -99.45056478986435900000); + aWeights.ChangeValue(6, 21) = +1.00966641434734750000; + aPoles.ChangeValue(6, 21) = gp_Pnt(+40.68431826182812500000, +0.00000000000000415229, -100.68882169811890000000); + aWeights.ChangeValue(6, 22) = +1.00966876842241240000; + aPoles.ChangeValue(6, 22) = gp_Pnt(+33.74965652868991100000, +0.00000000000000595055, -101.73819405254569000000); + aWeights.ChangeValue(6, 23) = +1.00967255617655690000; + aPoles.ChangeValue(6, 23) = gp_Pnt(+19.83474481990451800000, +0.00000000000000626687, -103.45778313292877000000); + aWeights.ChangeValue(6, 24) = +1.00967399859793900000; + aPoles.ChangeValue(6, 24) = gp_Pnt(+12.85396744583563800000, +0.00000000000000961706, -104.12796934503771000000); + aWeights.ChangeValue(6, 25) = +1.00967501382969150000; + aPoles.ChangeValue(6, 25) = gp_Pnt(+5.85612456199985140000, +0.00000000000001451316, -104.60783896197547000000); + aWeights.ChangeValue(6, 26) = +1.00967561936958040000; + aPoles.ChangeValue(6, 26) = gp_Pnt(-1.15266320632332260000, +0.00000000000001739414, -104.89689790453474000000); + aWeights.ChangeValue(6, 27) = +1.00967582483410530000; + aPoles.ChangeValue(6, 27) = gp_Pnt(-8.16630892272242730000, +0.00000000000001688939, -104.99487618531697000000); + aWeights.ChangeValue(6, 28) = +1.00967563195849790000; + aPoles.ChangeValue(6, 28) = gp_Pnt(-15.17875958769639600000, +0.00000000000001381871, -104.90172793642448000000); + aWeights.ChangeValue(6, 29) = +1.00967503459672230000; + aPoles.ChangeValue(6, 29) = gp_Pnt(-22.18399638815323600000, +0.00000000000001119232, -104.61763141615558000000); + aWeights.ChangeValue(6, 30) = +1.00967300468446440000; + aPoles.ChangeValue(6, 30) = gp_Pnt(-36.16808769247344200000, +0.00000000000001926896, -103.66834538209933000000); + aWeights.ChangeValue(6, 31) = +1.00967156777535520000; + aPoles.ChangeValue(6, 31) = gp_Pnt(-43.14695215605046700000, +0.00000000000002086710, -103.00315490229345000000); + aWeights.ChangeValue(6, 32) = +1.00966969979090850000; + aPoles.ChangeValue(6, 32) = gp_Pnt(-50.10664482445217500000, +0.00000000000002115378, -102.14781821392242000000); + aWeights.ChangeValue(6, 33) = +1.00966737970297340000; + aPoles.ChangeValue(6, 33) = gp_Pnt(-57.04121502398449900000, +0.00000000000002158031, -101.10296070558179000000); + aWeights.ChangeValue(6, 34) = +1.00966457365849420000; + aPoles.ChangeValue(6, 34) = gp_Pnt(-63.94474533155499800000, +0.00000000000002290082, -99.86943240681669900000); + aWeights.ChangeValue(6, 35) = +1.00966123497950670000; + aPoles.ChangeValue(6, 35) = gp_Pnt(-70.81135197820185600000, +0.00000000000002517228, -98.44830786498150100000); + aWeights.ChangeValue(6, 36) = +1.00965730416314160000; + aPoles.ChangeValue(6, 36) = gp_Pnt(-77.63518524225725100000, +0.00000000000002775445, -96.84088598857995600000); + aWeights.ChangeValue(6, 37) = +1.00965057624219750000; + aPoles.ChangeValue(6, 37) = gp_Pnt(-87.55609990295042200000, +0.00000000000002423047, -94.21659328767886200000); + aWeights.ChangeValue(6, 38) = +1.00964829695753600000; + aPoles.ChangeValue(6, 38) = gp_Pnt(-90.69129861847109500000, +0.00000000000002587407, -93.34466557470412300000); + aWeights.ChangeValue(6, 39) = +1.00964586498085130000; + aPoles.ChangeValue(6, 39) = gp_Pnt(-93.81544408055053500000, +0.00000000000003006614, -92.43305897005754400000); + aWeights.ChangeValue(6, 40) = +1.00964327207695040000; + aPoles.ChangeValue(6, 40) = gp_Pnt(-96.92795589621758300000, +0.00000000000003388207, -91.48193626907418300000); + aWeights.ChangeValue(6, 41) = +1.00964050782223150000; + aPoles.ChangeValue(6, 41) = gp_Pnt(-100.02825520717420000000, +0.00000000000003564727, -90.49147079864104600000); + aWeights.ChangeValue(6, 42) = +1.00963755960468200000; + aPoles.ChangeValue(6, 42) = gp_Pnt(-103.11576472135789000000, +0.00000000000003493709, -89.46184640324143800000); + aWeights.ChangeValue(6, 43) = +1.00963441262388120000; + aPoles.ChangeValue(6, 43) = gp_Pnt(-106.18990874397944000000, +0.00000000000003257692, -88.39325742978746800000); + aWeights.ChangeValue(6, 44) = +1.00962747055172470000; + aPoles.ChangeValue(6, 44) = gp_Pnt(-112.54574015681582000000, +0.00000000000006160655, -86.09336936272072200000); + aWeights.ChangeValue(6, 45) = +1.00962344856191890000; + aPoles.ChangeValue(6, 45) = gp_Pnt(-115.82520602454126000000, -0.00000000000003931317, -84.85588414554271700000); + aWeights.ChangeValue(6, 46) = +1.00961960432502520000; + aPoles.ChangeValue(6, 46) = gp_Pnt(-119.08778487668772000000, +0.00000000000016494845, -83.57368219250022900000); + aWeights.ChangeValue(6, 47) = +1.00961486341637220000; + aPoles.ChangeValue(6, 47) = gp_Pnt(-122.33277704237545000000, -0.00000000000006102663, -82.24707666574315100000); + aWeights.ChangeValue(6, 48) = +1.00961029578642010000; + aPoles.ChangeValue(6, 48) = gp_Pnt(-125.55945424028559000000, +0.00000000000005443726, -80.87630621413205700000); + aWeights.ChangeValue(6, 49) = +1.00960520453872830000; + aPoles.ChangeValue(6, 49) = gp_Pnt(-128.76711471386264000000, +0.00000000000006731284, -79.46169679871513800000); + aWeights.ChangeValue(6, 50) = +1.00959965618806670000; + aPoles.ChangeValue(6, 50) = gp_Pnt(-131.95505034236234000000, +0.00000000000001744703, -78.00355594499717400000); + aWeights.ChangeValue(6, 51) = +1.00958841592259230000; + aPoles.ChangeValue(6, 51) = gp_Pnt(-138.06383173526737000000, +0.00000000000005091738, -75.10807262033468100000); + aWeights.ChangeValue(6, 52) = +1.00958190609477040000; + aPoles.ChangeValue(6, 52) = gp_Pnt(-140.98751167669514000000, +0.00000000000001249767, -73.67671445695528100000); + aWeights.ChangeValue(6, 53) = +1.00957719226123470000; + aPoles.ChangeValue(6, 53) = gp_Pnt(-143.89297197091258000000, +0.00000000000004304958, -72.20827197874005800000); + aWeights.ChangeValue(6, 54) = +1.00956830736954160000; + aPoles.ChangeValue(6, 54) = gp_Pnt(-146.77976177895343000000, +0.00000000000014315600, -70.70325097869228200000); + aWeights.ChangeValue(6, 55) = +1.00956295195680430000; + aPoles.ChangeValue(6, 55) = gp_Pnt(-149.64716302220674000000, -0.00000000000013374459, -69.16163316263994400000); + aWeights.ChangeValue(6, 56) = +1.00955425555763600000; + aPoles.ChangeValue(6, 56) = gp_Pnt(-152.49476001470052000000, +0.00000000000014982315, -67.58397318476696100000); + aWeights.ChangeValue(6, 57) = +1.00954602613024340000; + aPoles.ChangeValue(6, 57) = gp_Pnt(-155.32190503332637000000, -0.00000000000000021066, -65.97043121899140800000); + aWeights.ChangeValue(6, 58) = +1.00952742278739690000; + aPoles.ChangeValue(6, 58) = gp_Pnt(-161.15007234465017000000, -0.00000000000001992904, -62.54527347940126700000); + aWeights.ChangeValue(6, 59) = +1.00951486183122910000; + aPoles.ChangeValue(6, 59) = gp_Pnt(-164.14837014605524000000, +0.00000000000023572067, -60.72896647597298900000); + aWeights.ChangeValue(6, 60) = +1.00950821186278380000; + aPoles.ChangeValue(6, 60) = gp_Pnt(-167.11960531963629000000, -0.00000000000028988207, -58.86870049528032900000); + aWeights.ChangeValue(6, 61) = +1.00948761363721440000; + aPoles.ChangeValue(6, 61) = gp_Pnt(-170.06906478280905000000, +0.00000000000040689923, -56.97372124744497800000); + aWeights.ChangeValue(6, 62) = +1.00948175483910860000; + aPoles.ChangeValue(6, 62) = gp_Pnt(-172.98765254825670000000, -0.00000000000024250881, -55.03312548926784600000); + aWeights.ChangeValue(6, 63) = +1.00946082358368820000; + aPoles.ChangeValue(6, 63) = gp_Pnt(-175.88148729884773000000, +0.00000000000015443744, -53.05496328096450000000); + aWeights.ChangeValue(6, 64) = +1.00944596410276510000; + aPoles.ChangeValue(6, 64) = gp_Pnt(-178.74719668858941000000, +0.00000000000002184305, -51.03719587787818300000); + aWeights.ChangeValue(6, 65) = +1.00942605045267690000; + aPoles.ChangeValue(6, 65) = gp_Pnt(-181.58512029181043000000, +0.00000000000003863576, -48.98084041218928800000); + aWeights.ChangeValue(6, 66) = +1.00940832657292460000; + aPoles.ChangeValue(6, 66) = gp_Pnt(-184.22041885135505000000, +0.00000000000012642202, -47.07128183802177500000); + aWeights.ChangeValue(6, 67) = +1.00938358350016230000; + aPoles.ChangeValue(6, 67) = gp_Pnt(-186.83172267077580000000, -0.00000000000026075896, -45.12863792869809700000); + aWeights.ChangeValue(6, 68) = +1.00937745534316470000; + aPoles.ChangeValue(6, 68) = gp_Pnt(-189.41814135962036000000, +0.00000000000050815389, -43.15221363464823400000); + aWeights.ChangeValue(6, 69) = +1.00932110415609880000; + aPoles.ChangeValue(6, 69) = gp_Pnt(-191.98049421722968000000, -0.00000000000036869153, -41.14519558079494000000); + aWeights.ChangeValue(6, 70) = +1.00934018958992230000; + aPoles.ChangeValue(6, 70) = gp_Pnt(-194.51554398045388000000, +0.00000000000024701945, -39.10283303403318900000); + aWeights.ChangeValue(6, 71) = +1.00926513417534820000; + aPoles.ChangeValue(6, 71) = gp_Pnt(-197.02654362639632000000, +0.00000000000002378284, -37.03182458375535900000); + aWeights.ChangeValue(6, 72) = +1.00924284324015100000; + aPoles.ChangeValue(6, 72) = gp_Pnt(-199.50902604112426000000, +0.00000000000001468063, -34.92696457232537500000); + aWeights.ChangeValue(6, 73) = +1.00920104311988210000; + aPoles.ChangeValue(6, 73) = gp_Pnt(-201.96417476016930000000, +0.00000000000004485301, -32.79087292323346500000); + aWeights.ChangeValue(6, 74) = +1.00917029694376930000; + aPoles.ChangeValue(6, 74) = gp_Pnt(-204.41947086956830000000, +0.00000000000007013856, -30.65436716589900700000); + aWeights.ChangeValue(6, 75) = +1.00906597799622610000; + aPoles.ChangeValue(6, 75) = gp_Pnt(-206.84718146821811000000, -0.00000000000006381675, -28.48746943619916600000); + aWeights.ChangeValue(6, 76) = +1.00920552993238920000; + aPoles.ChangeValue(6, 76) = gp_Pnt(-209.24487385523256000000, +0.00000000000020688933, -26.28443183778934900000); + aWeights.ChangeValue(6, 77) = +1.00876475817276390000; + aPoles.ChangeValue(6, 77) = gp_Pnt(-211.61934752962611000000, -0.00000000000012087895, -24.05869960942788700000); + aWeights.ChangeValue(6, 78) = +1.00888387250480620000; + aPoles.ChangeValue(6, 78) = gp_Pnt(-213.96155431166437000000, +0.00000000000019025578, -21.80066237623914200000); + aWeights.ChangeValue(6, 79) = +1.00881670070678450000; + aPoles.ChangeValue(6, 79) = gp_Pnt(-216.26151615033589000000, -0.00000000000009572292, -19.49741392382435400000); + aWeights.ChangeValue(6, 80) = +1.00875338528797620000; + aPoles.ChangeValue(6, 80) = gp_Pnt(-218.54531424806936000000, +0.00000000000008182630, -17.17704407009146500000); + aWeights.ChangeValue(6, 81) = +1.00842683370719580000; + aPoles.ChangeValue(6, 81) = gp_Pnt(-220.79435406720884000000, +0.00000000000004973799, -14.82789528118522200000); + aWeights.ChangeValue(7, 1) = +1.02986327036737910000; + aPoles.ChangeValue(7, 1) = gp_Pnt(+133.20307692191452000000, -0.00000000000000177636, -68.87095947031473000000); + aWeights.ChangeValue(7, 2) = +1.02989244478762340000; + aPoles.ChangeValue(7, 2) = gp_Pnt(+130.12738123407763000000, -0.00000000000000516390, -70.57040146390383500000); + aWeights.ChangeValue(7, 3) = +1.02991676091110000000; + aPoles.ChangeValue(7, 3) = gp_Pnt(+127.02840986317391000000, +0.00000000000000554535, -72.22789464235242500000); + aWeights.ChangeValue(7, 4) = +1.02993613450137910000; + aPoles.ChangeValue(7, 4) = gp_Pnt(+123.90694758506712000000, -0.00000000000000702621, -73.84302715009133100000); + aWeights.ChangeValue(7, 5) = +1.02995970896171030000; + aPoles.ChangeValue(7, 5) = gp_Pnt(+120.76360256847768000000, -0.00000000000000047370, -75.41549467632542300000); + aWeights.ChangeValue(7, 6) = +1.02998196300924330000; + aPoles.ChangeValue(7, 6) = gp_Pnt(+117.59908279457284000000, +0.00000000000000772901, -76.94495426059752700000); + aWeights.ChangeValue(7, 7) = +1.02999781361776170000; + aPoles.ChangeValue(7, 7) = gp_Pnt(+114.41407453952652000000, -0.00000000000000327310, -78.43108601253017300000); + aWeights.ChangeValue(7, 8) = +1.03001626830282000000; + aPoles.ChangeValue(7, 8) = gp_Pnt(+111.20931631680004000000, +0.00000000000000421483, -79.87356087705671800000); + aWeights.ChangeValue(7, 9) = +1.03004822145821140000; + aPoles.ChangeValue(7, 9) = gp_Pnt(+104.76172782897289000000, +0.00000000000000259283, -82.67059011797552200000); + aWeights.ChangeValue(7, 10) = +1.03006364818919470000; + aPoles.ChangeValue(7, 10) = gp_Pnt(+101.51889932580750000000, +0.00000000000000793496, -84.02514647707548100000); + aWeights.ChangeValue(7, 11) = +1.03007725635610380000; + aPoles.ChangeValue(7, 11) = gp_Pnt(+98.25768758130365700000, +0.00000000000000127608, -85.33546669488836800000); + aWeights.ChangeValue(7, 12) = +1.03009045031501540000; + aPoles.ChangeValue(7, 12) = gp_Pnt(+94.97880175952953200000, +0.00000000000000289709, -86.60126064632369500000); + aWeights.ChangeValue(7, 13) = +1.03010285398165520000; + aPoles.ChangeValue(7, 13) = gp_Pnt(+91.68295682468645700000, +0.00000000000000548904, -87.82224920548925700000); + aWeights.ChangeValue(7, 14) = +1.03011393120368040000; + aPoles.ChangeValue(7, 14) = gp_Pnt(+88.37086140882031800000, -0.00000000000000004450, -88.99816853898946100000); + aWeights.ChangeValue(7, 15) = +1.03012484065781210000; + aPoles.ChangeValue(7, 15) = gp_Pnt(+85.04324466385365600000, +0.00000000000000407116, -90.12875955698966400000); + aWeights.ChangeValue(7, 16) = +1.03015471267321310000; + aPoles.ChangeValue(7, 16) = gp_Pnt(+75.01621211174902700000, +0.00000000000001208092, -93.38380423550353300000); + aWeights.ChangeValue(7, 17) = +1.03017194800922480000; + aPoles.ChangeValue(7, 17) = gp_Pnt(+68.27251352067813200000, +0.00000000000001147779, -95.37146758037383200000); + aWeights.ChangeValue(7, 18) = +1.03018680682765580000; + aPoles.ChangeValue(7, 18) = gp_Pnt(+61.47507566136914600000, +0.00000000000000851456, -97.17487791831784700000); + aWeights.ChangeValue(7, 19) = +1.03019958109549560000; + aPoles.ChangeValue(7, 19) = gp_Pnt(+54.62953031922813800000, +0.00000000000000645560, -98.79238303220959900000); + aWeights.ChangeValue(7, 20) = +1.03021050389503310000; + aPoles.ChangeValue(7, 20) = gp_Pnt(+47.74179355100338300000, +0.00000000000000683493, -100.22257163394704000000); + aWeights.ChangeValue(7, 21) = +1.03021974942385920000; + aPoles.ChangeValue(7, 21) = gp_Pnt(+40.81806392732334400000, +0.00000000000000945638, -101.46427420633951000000); + aWeights.ChangeValue(7, 22) = +1.03022743299486530000; + aPoles.ChangeValue(7, 22) = gp_Pnt(+33.86482072309787100000, +0.00000000000001239365, -102.51656369616552000000); + aWeights.ChangeValue(7, 23) = +1.03023979631718960000; + aPoles.ChangeValue(7, 23) = gp_Pnt(+19.91267581058432200000, +0.00000000000001269021, -104.24092170462040000000); + aWeights.ChangeValue(7, 24) = +1.03024450452679180000; + aPoles.ChangeValue(7, 24) = gp_Pnt(+12.91322103073442500000, +0.00000000000001310657, -104.91296575233191000000); + aWeights.ChangeValue(7, 25) = +1.03024781840890150000; + aPoles.ChangeValue(7, 25) = gp_Pnt(+5.89663552968925500000, +0.00000000000001362222, -105.39416639705574000000); + aWeights.ChangeValue(7, 26) = +1.03024979501191980000; + aPoles.ChangeValue(7, 26) = gp_Pnt(-1.13093554742009240000, +0.00000000000001442955, -105.68402704533355000000); + aWeights.ChangeValue(7, 27) = +1.03025046568879810000; + aPoles.ChangeValue(7, 27) = gp_Pnt(-8.16338049757019310000, +0.00000000000001553070, -105.78227646648484000000); + aWeights.ChangeValue(7, 28) = +1.03024983609703620000; + aPoles.ChangeValue(7, 28) = gp_Pnt(-15.19462185431612500000, +0.00000000000001673746, -105.68886888131540000000); + aWeights.ChangeValue(7, 29) = +1.03024788619868390000; + aPoles.ChangeValue(7, 29) = gp_Pnt(-22.21861718693262200000, +0.00000000000001767135, -105.40398398356824000000); + aWeights.ChangeValue(7, 30) = +1.03024126030624560000; + aPoles.ChangeValue(7, 30) = gp_Pnt(-36.24014829916134100000, +0.00000000000002019891, -104.45206611492652000000); + aWeights.ChangeValue(7, 31) = +1.03023657011944200000; + aPoles.ChangeValue(7, 31) = gp_Pnt(-43.23771519136024500000, +0.00000000000002161068, -103.78502949380328000000); + aWeights.ChangeValue(7, 32) = +1.03023047292900840000; + aPoles.ChangeValue(7, 32) = gp_Pnt(-50.21605719916001900000, +0.00000000000002249329, -102.92731708926736000000); + aWeights.ChangeValue(7, 33) = +1.03022290017099440000; + aPoles.ChangeValue(7, 33) = gp_Pnt(-57.16920057960702200000, +0.00000000000002320995, -101.87955571848956000000); + aWeights.ChangeValue(7, 34) = +1.03021374148842140000; + aPoles.ChangeValue(7, 34) = gp_Pnt(-64.09120253994868200000, +0.00000000000002399266, -100.64259867222304000000); + aWeights.ChangeValue(7, 35) = +1.03020284473128120000; + aPoles.ChangeValue(7, 35) = gp_Pnt(-70.97615252947152000000, +0.00000000000002494226, -99.21752532044712300000); + aWeights.ChangeValue(7, 36) = +1.03019001595653670000; + aPoles.ChangeValue(7, 36) = gp_Pnt(-77.81817349811507300000, +0.00000000000002602838, -97.60564061068184600000); + aWeights.ChangeValue(7, 37) = +1.03016805964614980000; + aPoles.ChangeValue(7, 37) = gp_Pnt(-87.76549855749630100000, +0.00000000000002703745, -94.97405836608523100000); + aWeights.ChangeValue(7, 38) = +1.03016062145972500000; + aPoles.ChangeValue(7, 38) = gp_Pnt(-90.90906843451735100000, +0.00000000000002735353, -94.09969925934423400000); + aWeights.ChangeValue(7, 39) = +1.03015268516758060000; + aPoles.ChangeValue(7, 39) = gp_Pnt(-94.04154842308000200000, +0.00000000000002795160, -93.18554984223239000000); + aWeights.ChangeValue(7, 40) = +1.03014422393874510000; + aPoles.ChangeValue(7, 40) = gp_Pnt(-97.16235536263198500000, +0.00000000000002873660, -92.23177350871787900000); + aWeights.ChangeValue(7, 41) = +1.03013520381253840000; + aPoles.ChangeValue(7, 41) = gp_Pnt(-100.27090735629974000000, +0.00000000000002960449, -91.23854430518403500000); + aWeights.ChangeValue(7, 42) = +1.03012558369857450000; + aPoles.ChangeValue(7, 42) = gp_Pnt(-103.36662387191370000000, +0.00000000000003044224, -90.20604688574815100000); + aWeights.ChangeValue(7, 43) = +1.03011531537676040000; + aPoles.ChangeValue(7, 43) = gp_Pnt(-106.44892584135401000000, +0.00000000000003112785, -89.13447646370049400000); + aWeights.ChangeValue(7, 44) = +1.03009266486582220000; + aPoles.ChangeValue(7, 44) = gp_Pnt(-112.82164316087234000000, +0.00000000000002877514, -86.82815610446842000000); + aWeights.ChangeValue(7, 45) = +1.03007954250937140000; + aPoles.ChangeValue(7, 45) = gp_Pnt(-116.10982863064515000000, +0.00000000000005217709, -85.58719260568324200000); + aWeights.ChangeValue(7, 46) = +1.03006700046765860000; + aPoles.ChangeValue(7, 46) = gp_Pnt(-119.38108228759732000000, -0.00000000000000364635, -84.30140001571530200000); + aWeights.ChangeValue(7, 47) = +1.03005153385603830000; + aPoles.ChangeValue(7, 47) = gp_Pnt(-122.63466837574235000000, +0.00000000000007773224, -82.97105629274108200000); + aWeights.ChangeValue(7, 48) = +1.03003663316235050000; + aPoles.ChangeValue(7, 48) = gp_Pnt(-125.86988610286646000000, +0.00000000000000501775, -81.59643931580511400000); + aWeights.ChangeValue(7, 49) = +1.03002002524069390000; + aPoles.ChangeValue(7, 49) = gp_Pnt(-129.08600965998806000000, +0.00000000000004872530, -80.17785297868806500000); + aWeights.ChangeValue(7, 50) = +1.03000192732158440000; + aPoles.ChangeValue(7, 50) = gp_Pnt(-132.28232849510800000000, +0.00000000000003627431, -78.71561001568775900000); + aWeights.ChangeValue(7, 51) = +1.02996526567106140000; + aPoles.ChangeValue(7, 51) = gp_Pnt(-138.40719443250111000000, +0.00000000000004030865, -75.81195871455292900000); + aWeights.ChangeValue(7, 52) = +1.02994403451619650000; + aPoles.ChangeValue(7, 52) = gp_Pnt(-141.33856968181306000000, +0.00000000000003444592, -74.37651555974527200000); + aWeights.ChangeValue(7, 53) = +1.02992866105480000000; + aPoles.ChangeValue(7, 53) = gp_Pnt(-144.25171811139330000000, +0.00000000000003429445, -72.90395453557894700000); + aWeights.ChangeValue(7, 54) = +1.02989968743351530000; + aPoles.ChangeValue(7, 54) = gp_Pnt(-147.14603336223070000000, +0.00000000000004355038, -71.39457006641885100000); + aWeights.ChangeValue(7, 55) = +1.02988222474475720000; + aPoles.ChangeValue(7, 55) = gp_Pnt(-150.02095857157173000000, +0.00000000000003217269, -69.84863841933133700000); + aWeights.ChangeValue(7, 56) = +1.02985386954430420000; + aPoles.ChangeValue(7, 56) = gp_Pnt(-152.87595706513403000000, +0.00000000000003648661, -68.26644064265008200000); + aWeights.ChangeValue(7, 57) = +1.02982704006085530000; + aPoles.ChangeValue(7, 57) = gp_Pnt(-155.71041601974636000000, +0.00000000000003591181, -66.64830754728993200000); + aWeights.ChangeValue(7, 58) = +1.02976639514271140000; + aPoles.ChangeValue(7, 58) = gp_Pnt(-161.55369960091491000000, +0.00000000000003646415, -63.21332070345936700000); + aWeights.ChangeValue(7, 59) = +1.02972545417744080000; + aPoles.ChangeValue(7, 59) = gp_Pnt(-164.55974256681068000000, +0.00000000000003294676, -61.39167299907511900000); + aWeights.ChangeValue(7, 60) = +1.02970377642180270000; + aPoles.ChangeValue(7, 60) = gp_Pnt(-167.53873683551103000000, +0.00000000000002190344, -59.52621075357659900000); + aWeights.ChangeValue(7, 61) = +1.02963665582099750000; + aPoles.ChangeValue(7, 61) = gp_Pnt(-170.49570646978711000000, +0.00000000000009010479, -57.62531748377598000000); + aWeights.ChangeValue(7, 62) = +1.02961756328110620000; + aPoles.ChangeValue(7, 62) = gp_Pnt(-173.42176702363508000000, -0.00000000000003499440, -55.67944052993496500000); + aWeights.ChangeValue(7, 63) = +1.02954937293567860000; + aPoles.ChangeValue(7, 63) = gp_Pnt(-176.32284460610933000000, +0.00000000000007636921, -53.69521656711459900000); + aWeights.ChangeValue(7, 64) = +1.02950097342681770000; + aPoles.ChangeValue(7, 64) = gp_Pnt(-179.19569709355173000000, +0.00000000000003273955, -51.67161593723249500000); + aWeights.ChangeValue(7, 65) = +1.02943612532291810000; + aPoles.ChangeValue(7, 65) = gp_Pnt(-182.04053139917158000000, +0.00000000000003996803, -49.60917258111981500000); + aWeights.ChangeValue(7, 66) = +1.02937840445762090000; + aPoles.ChangeValue(7, 66) = gp_Pnt(-184.68250151172640000000, +0.00000000000004112926, -47.69381589112448700000); + aWeights.ChangeValue(7, 67) = +1.02929786839945800000; + aPoles.ChangeValue(7, 67) = gp_Pnt(-187.30004443981446000000, +0.00000000000003629801, -45.74517623046489900000); + aWeights.ChangeValue(7, 68) = +1.02927785532615720000; + aPoles.ChangeValue(7, 68) = gp_Pnt(-189.89358418563035000000, +0.00000000000003708012, -43.76295173174737800000); + aWeights.ChangeValue(7, 69) = +1.02909457173661250000; + aPoles.ChangeValue(7, 69) = gp_Pnt(-192.46070903458983000000, +0.00000000000005500515, -41.74904085552218200000); + aWeights.ChangeValue(7, 70) = +1.02915656102268340000; + aPoles.ChangeValue(7, 70) = gp_Pnt(-195.00353322314638000000, +0.00000000000002645256, -39.70148425813464900000); + aWeights.ChangeValue(7, 71) = +1.02891246604057510000; + aPoles.ChangeValue(7, 71) = gp_Pnt(-197.51895024482548000000, +0.00000000000005006422, -37.62251287581096900000); + aWeights.ChangeValue(7, 72) = +1.02884001996279940000; + aPoles.ChangeValue(7, 72) = gp_Pnt(-200.00717902020989000000, +0.00000000000003866246, -35.51147139839754600000); + aWeights.ChangeValue(7, 73) = +1.02870418206103280000; + aPoles.ChangeValue(7, 73) = gp_Pnt(-202.46745722827831000000, +0.00000000000003996803, -33.36845405838467800000); + aWeights.ChangeValue(7, 74) = +1.02860417892808040000; + aPoles.ChangeValue(7, 74) = gp_Pnt(-204.92874075079348000000, +0.00000000000003952569, -31.22492832365916000000); + aWeights.ChangeValue(7, 75) = +1.02826579045574770000; + aPoles.ChangeValue(7, 75) = gp_Pnt(-207.35951843182116000000, +0.00000000000002864861, -29.04902036970887700000); + aWeights.ChangeValue(7, 76) = +1.02871793966685040000; + aPoles.ChangeValue(7, 76) = gp_Pnt(-209.76815931164757000000, +0.00000000000007786791, -26.84449461829588300000); + aWeights.ChangeValue(7, 77) = +1.02728787827248790000; + aPoles.ChangeValue(7, 77) = gp_Pnt(-212.13952611955784000000, -0.00000000000002645359, -24.59453985262025100000); + aWeights.ChangeValue(7, 78) = +1.02767535385751650000; + aPoles.ChangeValue(7, 78) = gp_Pnt(-214.48523983715771000000, +0.00000000000011316462, -22.34028621398329100000); + aWeights.ChangeValue(7, 79) = +1.02745809923196680000; + aPoles.ChangeValue(7, 79) = gp_Pnt(-216.79261871005519000000, -0.00000000000002978790, -20.02558452892611700000); + aWeights.ChangeValue(7, 80) = +1.02725110106353260000; + aPoles.ChangeValue(7, 80) = gp_Pnt(-219.08116944862113000000, +0.00000000000005732296, -17.69632354506026700000); + aWeights.ChangeValue(7, 81) = +1.02619749797986360000; + aPoles.ChangeValue(7, 81) = gp_Pnt(-221.32510969435936000000, +0.00000000000004618528, -15.33078661161192400000); + } + //// + + const Handle(Geom_Surface) aS1 = new Geom_BSplineSurface(aPoles, aWeights, aUKnots, aVKnots, aUMult, aVMult, aUDegree, aVDegree); + + char buff[1024]; + + Sprintf(buff, "%s_1", theArgVal[1]); + DrawTrSurf::Set(buff, aS1); + theDI << buff << " "; + + Sprintf(buff, "%s_2", theArgVal[1]); + DrawTrSurf::Set(buff, aS2); + theDI << buff << "\n"; + + return 0; +} + +namespace AllocTest +{ + // The test is based of occupying of all available virtual memory. + // Obviously it has no sense on 64-bit platforms. + + enum AllocTestStatus + { + NotApplicable = 0x1, + OUMCatchOK = 0x2, + OUMCatchFail = 0x4 + }; + + template int test() + { + // non-32-bit implementation + return NotApplicable; + } + + template<> int test<4>() + { + // 32-bit implementation + NCollection_List aList; + const Standard_Integer aBlockSizes[] = {100000, 10000, 10}; + int aStatus = 0; + + // start populate memory with blocks of large size, then + // smaller ones and so on according to content of the array aBlockSizes + for (size_t i=0; i < sizeof(aBlockSizes)/sizeof(int); i++) + { + try + { + for (;;) + aList.Append(Standard::Allocate(aBlockSizes[i])); + } + catch (Standard_Failure) + { + aStatus |= OUMCatchOK; + } + catch (...) + { + aStatus |= OUMCatchFail; + break; + } + } + // release all allocated blocks + for (NCollection_List::Iterator it(aList); it.More(); it.Next()) + { + Standard::Free(it.Value()); + } + return aStatus; + } +} + +//======================================================================= +//function : OCC24836 +//purpose : +//======================================================================= +static Standard_Integer OCC24836 (Draw_Interpretor& theDI, Standard_Integer n, const char** a) +{ + if (n != 1) + { + theDI << "Usage : " << a[0] << "\n"; + return 1; + } + + int aStatus = AllocTest::test(); + + if (aStatus & AllocTest::NotApplicable) + theDI << "This test case is not applicable for 64-bit and higher platforms\n"; + if (aStatus & AllocTest::OUMCatchOK) + theDI << "out-of-memory has been caught: OK\n"; + if (aStatus & AllocTest::OUMCatchFail) + theDI << "Error: out-of-memory is not always caught\n"; + return 0; +} + + +//======================================================================= +//function : OCC27021 +//purpose : Tests performance of obtaining geometry (points) via topological +// exploring or fetching the geometry. +//======================================================================= + +// Fetch via topology +static std::pair getVerticesA(const TopoDS_Edge& theEdge) +{ + std::pair result; + + static TopoDS_Vertex aFirst, aLast; + TopExp::Vertices(theEdge, aFirst, aLast, Standard_True); + + result.first = BRep_Tool::Pnt(aFirst); + result.second = BRep_Tool::Pnt(aLast); + + return result; +} + +//Geometrical way +static std::pair getVerticesB(const TopoDS_Edge& theEdge) +{ + Standard_Real first; + Standard_Real last; + + Handle(Geom_Curve) curve = BRep_Tool::Curve(theEdge, first, last); + + std::pair result; + + if (theEdge.Orientation() == TopAbs_REVERSED) + { + curve->D0(first, result.second); + curve->D0(last, result.first); + } + else + { + curve->D0(first, result.first); + curve->D0(last, result.second); + } + return result; +} + + + +static Standard_Integer OCC27021(Draw_Interpretor& theDI, + Standard_Integer theNArg, + const char ** theArgVal) +{ + if (theNArg != 2) + { + cout << "Use: " << theArgVal[0] << " shape" << endl; + return 1; + } + + TopoDS_Shape shape (DBRep::Get(theArgVal[1])); + + TopTools_IndexedMapOfShape shape_faces; + TopExp::MapShapes(shape, TopAbs_FACE, shape_faces); + + // Pick a single face which shows the problem. + TopoDS_Face face = TopoDS::Face(shape_faces(10)); + TopTools_IndexedMapOfShape face_edges; + TopExp::MapShapes(face, TopAbs_EDGE, face_edges); + TopoDS_Edge edge = TopoDS::Edge(face_edges(2)); + + Standard_Integer iterations = 100000000; + + std::pair vertices; + clock_t t = clock(); + + theDI << "\nRetrieving " << iterations << " vertices using approach A)..."; + for (int i = 0; i < iterations; ++i) + { + vertices = getVerticesA(edge); + } + theDI << "done in " << (clock() - t) / (double)CLOCKS_PER_SEC << " seconds\n"; + t = clock(); + + theDI << "\nRetrieving " << iterations << " vertices using approach B)..."; + for (int i = 0; i < iterations; ++i) + { + vertices = getVerticesB(edge); + } + theDI << "done in " << (clock() - t) / (double)CLOCKS_PER_SEC << " seconds\n"; + + return 0; +} + +//======================================================================= +//function : OCC27235 +//purpose : check presentation in GDT document +//======================================================================= +static Standard_Integer OCC27235 (Draw_Interpretor& theDI, Standard_Integer n, const char** a) +{ + if (n < 2) { + theDI<<"Use: OCC27235 Doc"; + return 1; + } + + Handle(TDocStd_Document) Doc; + DDocStd::GetDocument(a[1], Doc); + if ( Doc.IsNull() ) { theDI << a[1] << " is not a document\n"; return 1; } + Handle(XCAFDoc_DimTolTool) aDimTolTool= XCAFDoc_DocumentTool::DimTolTool(Doc->Main()); + Handle(XCAFDoc_ShapeTool) aShapeTool= XCAFDoc_DocumentTool::ShapeTool(Doc->Main()); + TopoDS_Compound aPresentations; + BRep_Builder B; + B.MakeCompound(aPresentations); + + TDF_LabelSequence aLabels; + aShapeTool->GetShapes(aLabels); + for ( Standard_Integer i=1; i <= aLabels.Length(); i++ ) + { + aShapeTool->GetSubShapes(aLabels.Value(i), aLabels); + } + + TDF_LabelSequence aGDTs; + aDimTolTool->GetDimensionLabels(aGDTs); + for (Standard_Integer i = 1; i <= aGDTs.Length(); i++) { + Handle(XCAFDoc_Dimension) aDimAttr; + if (!aGDTs.Value(i).FindAttribute(XCAFDoc_Dimension::GetID(),aDimAttr)) + continue; + Handle(XCAFDimTolObjects_DimensionObject) anObject = aDimAttr->GetObject(); + if (anObject.IsNull()) + continue; + TopoDS_Shape aShape = anObject->GetPresentation(); + if (!aShape.IsNull()) + B.Add(aPresentations, aShape); + } + + aGDTs.Clear(); + aDimTolTool->GetGeomToleranceLabels(aGDTs); + for (Standard_Integer i = 1; i <= aGDTs.Length(); i++) { + Handle(XCAFDoc_GeomTolerance) aGTAttr; + if (!aGDTs.Value(i).FindAttribute(XCAFDoc_GeomTolerance::GetID(),aGTAttr)) + continue; + Handle(XCAFDimTolObjects_GeomToleranceObject) anObject = aGTAttr->GetObject(); + if (anObject.IsNull()) + continue; + TopoDS_Shape aShape = anObject->GetPresentation(); + if (!aShape.IsNull()) + B.Add(aPresentations, aShape); + } + + for ( Standard_Integer i=1; i <= aLabels.Length(); i++ ) + { + TDF_LabelSequence aDatL; + if(aDimTolTool->GetRefDatumLabel(aLabels.Value(i), aDatL)) + { + for(Standard_Integer j = aDatL.Lower(); j <= aDatL.Upper(); j++) + { + Handle(XCAFDoc_Datum) aDat; + if(!aDatL.Value(j).FindAttribute(XCAFDoc_Datum::GetID(), aDat)) + continue; + Handle(XCAFDimTolObjects_DatumObject) anObject = aDat->GetObject(); + if (anObject.IsNull()) + continue; + TopoDS_Shape aShape = anObject->GetPresentation(); + if (!aShape.IsNull()) + B.Add(aPresentations, aShape); + } + } + } + + GProp_GProps aG; + BRepGProp::LinearProperties(aPresentations, aG); + gp_Pnt aPnt = aG.CentreOfMass(); + theDI << "Centre of mass: " << aPnt.X() << " " << aPnt.Y() << " " << aPnt.Z() << "\n"; + theDI << "Mass: " << aG.Mass() << "\n"; + + return 0; +} + +//======================================================================= +//function : OCC24836 +//purpose : +//======================================================================= +static Standard_Integer OCC26930(Draw_Interpretor& theDI, + Standard_Integer theNArg, + const char ** theArgVal) +{ + if (theNArg != 5) + { + cout << "Use: " << theArgVal[0] <<" surface curve start end" << endl; + return 1; + } + + + + + + Handle(Geom_Surface) aSurface = DrawTrSurf::GetSurface(theArgVal[1]); + Handle(Geom_Curve) aCurve = DrawTrSurf::GetCurve(theArgVal[2]); + Standard_Real aStart = Draw::Atof(theArgVal[3]); + Standard_Real anEnd = Draw::Atof(theArgVal[4]); + + //project + Handle (Geom2d_Curve) aPCurve; + + ShapeConstruct_ProjectCurveOnSurface aProj; + aProj.Init(aSurface, Precision::Confusion()); + { + try { + Handle (Geom_Curve) aTmpCurve = aCurve; //to use reference in Perform() + aProj.Perform (aTmpCurve, aStart, anEnd, aPCurve); + } catch (const Standard_Failure&) { + } + } + + //check results + if (aPCurve.IsNull()) { + theDI << "Error: pcurve is null\n"; + } + else { + if (aPCurve->IsKind(STANDARD_TYPE(Geom2d_Line))) { + theDI << "Pcurve is line: OK\n"; + } + else { + theDI << "Error: PCurve is not line\n"; + } + } + + return 0; +} + +//======================================================================= +//function : OCC27341 +//purpose : check exact HLR algorighm's work +//======================================================================= +static Standard_Integer OCC27341 (Draw_Interpretor& , Standard_Integer n, const char** a) +{ + if (n != 4) + { + cout << "Use: OCC27341 res shape axo/top/bottom/front/back/left/right" << endl; + return 1; + } + + TopoDS_Shape aShape = DBRep::Get(a[2]); + if (aShape.IsNull()) + return 1; + + gp_Pnt anOrigin(0.,0.,0.); + gp_Dir aNormal(0.57735026918962573, -0.57735026918962573, 0.57735026918962573); + gp_Ax2 anAxes(anOrigin, aNormal); + gp_Dir aDX = anAxes.XDirection(); + + HLRAppli_ReflectLines Reflector(aShape); + + if (strcmp(a[3],"axo") == 0) + { + aNormal.SetCoord(0.57735026918962573, -0.57735026918962573, 0.57735026918962573); + aDX.SetCoord(-0.40824829046386307, 0.40824829046386307, 0.81649658092772615); + } + else if (strcmp(a[3],"top") == 0) + { + aNormal.SetCoord(0,0,1); + aDX.SetCoord(0,1,0); + } + else if (strcmp(a[3],"bottom") == 0) + { + aNormal.SetCoord(0,0,-1); + aDX.SetCoord(0,-1,0); + } + else if (strcmp(a[3],"front") == 0) + { + aNormal.SetCoord(0,-1,0); + aDX.SetCoord(0,0,1); + } + else if (strcmp(a[3],"back") == 0) + { + aNormal.SetCoord(0,1,0); + aDX.SetCoord(0,0,1); + } + else if (strcmp(a[3],"left") == 0) + { + aNormal.SetCoord(-1,0,0); + aDX.SetCoord(0,0,1); + } + else if (strcmp(a[3],"right") == 0) + { + aNormal.SetCoord(1,0,0); + aDX.SetCoord(0,0,1); + } + + Reflector.SetAxes(aNormal.X(), aNormal.Y(), aNormal.Z(), + anOrigin.X(), anOrigin.Y(), anOrigin.Z(), + aDX.X(), aDX.Y(), aDX.Z()); + + Reflector.Perform(); + + TopoDS_Compound Result; + BRep_Builder BB; + BB.MakeCompound(Result); + + TopoDS_Shape SharpEdges = Reflector.GetCompoundOf3dEdges(HLRBRep_Sharp, Standard_True, Standard_False); + if (!SharpEdges.IsNull()) + BB.Add(Result, SharpEdges); + TopoDS_Shape OutLines = Reflector.GetCompoundOf3dEdges(HLRBRep_OutLine, Standard_True, Standard_False); + if (!OutLines.IsNull()) + BB.Add(Result, OutLines); + TopoDS_Shape SmoothEdges = Reflector.GetCompoundOf3dEdges(HLRBRep_Rg1Line, Standard_True, Standard_False); + if (!SmoothEdges.IsNull()) + BB.Add(Result, SmoothEdges); + + DBRep::Set(a[1], Result); + + return 0; +} + +//======================================================================= +//function : OCC27466 +//purpose : +//======================================================================= +static Standard_Integer OCC27466(Draw_Interpretor& theDI, + Standard_Integer theNArg, + const char ** theArgVal) +{ + if (theNArg != 4) + { + cout << "Use: " << theArgVal[0] << " face point start_pnt2d" << endl; + return 1; + } + + TopoDS_Face aFace = TopoDS::Face(DBRep::Get(theArgVal[1], TopAbs_FACE, Standard_True)); + if (aFace.IsNull()) + return 1; + gp_Pnt aPnt; + if (!DrawTrSurf::GetPoint(theArgVal[2], aPnt)) + return 1; + gp_Pnt2d aUV; + if (!DrawTrSurf::GetPoint2d(theArgVal[3], aUV)) + return 1; + BRepAdaptor_Surface aSurf(aFace); + + Standard_Real aTolU = Precision::PConfusion(); + Standard_Real aTolV = Precision::PConfusion(); + + Extrema_GenLocateExtPS anExtrema(aSurf, aTolU, aTolV); + anExtrema.Perform(aPnt, aUV.X(), aUV.Y(), Standard_True); + + if (!anExtrema.IsDone()) + { + theDI << "Error: Extrema is not done"; + } + else + { + Standard_Real aSqDist = anExtrema.SquareDistance(); + gp_Pnt aResPnt = anExtrema.Point().Value(); + Standard_Real u, v; + anExtrema.Point().Parameter(u, v); + gp_Pnt2d aResUV(u, v); + DrawTrSurf::Set((TCollection_AsciiString(theArgVal[2]) + "_res").ToCString(), aResPnt); + DrawTrSurf::Set((TCollection_AsciiString(theArgVal[3]) + "_res").ToCString(), aResUV); + theDI << theArgVal[2] << "_res and " << theArgVal[3] << "_res are created, dist=" << sqrt(aSqDist); + } + return 0; +} + +#include +#include +#include +#include + +namespace Parab2d_Bug26747 +{ + //Directrix and X-axe direction + gp_Ax2d Axes; + + //Focus + gp_Pnt2d FocusPoint; + + //Focal length + Standard_Real FocalLength; + + //Coordiantes of the vertex + Standard_Real VertX, VertY; + + //Parameter + Standard_Real Parameter; + + //Coefficients + Standard_Real Coeffs[6]; +} + +//======================================================================== +//function : OCC26747_CheckParabola +//purpose : Checks if created parabola is correct +//======================================================================== +static void OCC26747_CheckParabola(Draw_Interpretor& theDI, + const char *theName, + const Standard_Boolean theSense = Standard_True) +{ + const Standard_Real aCompareTol = 1.0e-12; + + // Directrix, Focus + GCE2d_MakeParabola aPrb(Parab2d_Bug26747::Axes, Parab2d_Bug26747::FocusPoint, theSense); + + DrawTrSurf::Set(theName, aPrb.Value()); + + gp_Pnt2d aVert(aPrb.Value()->Parab2d().Location()); + + theDI << "Focal Length: " << aPrb.Value()->Parab2d().Focal() << "\n"; + theDI << "Vertex (" << aVert.X() << ", " << aVert.Y() << ")\n"; + theDI << "Parameter = " << aPrb.Value()->Parab2d().Parameter() << "\n"; + + Standard_Real aF[6] = {RealLast(), RealLast(), RealLast(), + RealLast(), RealLast(), RealLast()}; + aPrb.Value()->Parab2d().Coefficients(aF[0], aF[1], aF[2], aF[3], aF[4], aF[5]); + theDI << "A = " << aF[0] << ", B = " << aF[1] << ", C = " << aF[2] << + ", D = " << aF[3] << ", E = " << aF[4] << ", F = " << aF[5] << "\n"; + + if(Abs(aPrb.Value()->Parab2d().Focal() - + Parab2d_Bug26747::FocalLength) > aCompareTol) + theDI << "Error in focal length computation!\n"; + + if( (Abs(aVert.X() - Parab2d_Bug26747::VertX) > aCompareTol) || + (Abs(aVert.Y() - Parab2d_Bug26747::VertY) > aCompareTol)) + theDI << "Error in vertex computation!\n"; + + if(Abs(aPrb.Value()->Parab2d().Parameter() - + Parab2d_Bug26747::Parameter) > aCompareTol) + theDI << "Error in parameter computation!\n"; + + for(int i = 0; i < 6; i++) + { + if(Abs(aF[i] - Parab2d_Bug26747::Coeffs[i]) > aCompareTol) + { + theDI << "Error in " << i << "-th coefficient computation!\n"; + } + } +} + +//======================================================================== +//function : OCC26747_1 +//purpose : Creates a 2D-parabola for testing +//======================================================================== +static Standard_Integer OCC26747_1(Draw_Interpretor& theDI, + Standard_Integer theNArg, + const char ** theArgVal) +{ + if(theNArg < 2) + { + theDI << "Use: OCC26747_1 result\n"; + return 1; + } + + //Expected parabola: + + // ^ Y + // | + // | + // | + // | + // | o + // | A o F + // | o x + // | o + // | o + // | + // ---------------------------> X + + // where + // Y-axe is the directrix of the parabola, + // A(0.5, 3.0) is a Vertex of the parabola, + // F(1.0, 3.0) is the focus of the parabola, + // Focal length is 0.5, + // Parameter of the parabola is 1. + // Equation: (y-3)^2=2*p*(x-0.5), i.e. (y-3)^2=2*(x-0.5) + // A * X^2 + B * Y^2 + 2*C*X*Y + 2*D*X + 2*E*Y + F = 0. + // OR + // 0 * X^2 + 1 * Y^2 + 2*0*X*Y + 2*(-1)*X + 2*(-3)*Y + 10 = 0. + + Parab2d_Bug26747::Axes = gp_Ax2d(gp_Pnt2d(0.0, 3.0), gp_Dir2d(0.0, 1.0)); + Parab2d_Bug26747::FocusPoint.SetCoord(1.0, 3.0); + + Parab2d_Bug26747::FocalLength = 0.5; + + Parab2d_Bug26747::VertX = 0.5; + Parab2d_Bug26747::VertY = 3.0; + + Parab2d_Bug26747::Parameter = 1.0; + + Parab2d_Bug26747::Coeffs[0] = 0.0; + Parab2d_Bug26747::Coeffs[1] = 1.0; + Parab2d_Bug26747::Coeffs[2] = 0.0; + Parab2d_Bug26747::Coeffs[3] = -1.0; + Parab2d_Bug26747::Coeffs[4] = -3.0; + Parab2d_Bug26747::Coeffs[5] = 10.0; + + OCC26747_CheckParabola(theDI, theArgVal[1]); + + return 0; +} + +//======================================================================= +//function : OCC26747_2 +//purpose : Creates a 2D-parabola for testing +//======================================================================= +static Standard_Integer OCC26747_2(Draw_Interpretor& theDI, + Standard_Integer theNArg, + const char ** theArgVal) +{ + if(theNArg < 2) + { + theDI << "Use: OCC26747_2 result\n"; + return 1; + } + + //Expected parabola: + + // ^ Y + // | + // o | + // o | + // F x o A | + // o | + // o | + // | + // <------------------------ + // X + + // where (in UCS - User Coordinate System, - which + // is shown in the picture): + // Y-axe is the directrix of the parabola, + // A(0.5, 3.0) is a Vertex of the parabola, + // F(1.0, 3.0) is the focus of the parabola. + // + // In WCS (World Coordinate System) these points have coordinates: + // A(-0.5, 3.0), F(-1.0, 3.0). + // + // Focal length is 0.5, + // Parameter of the parabola is 1. + // Equation (in WCS): (y-3)^2=2*p*(-x-0.5), i.e. (y-3)^2=2*(-x-0.5) + // A * X^2 + B * (Y^2) + 2*C*(X*Y) + 2*D*X + 2*E*Y + F = 0. + // 0 * X^2 + 1 * (Y^2) + 2*0*(X*Y) + 2*1*X + 2*(-3)*Y + 10 = 0. + + + Parab2d_Bug26747::Axes = gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(0.0, 1.0)); + Parab2d_Bug26747::FocusPoint.SetCoord(-1.0, 3.0); + + Parab2d_Bug26747::FocalLength = 0.5; + + Parab2d_Bug26747::VertX = -0.5; + Parab2d_Bug26747::VertY = 3.0; + + Parab2d_Bug26747::Parameter = 1.0; + + Parab2d_Bug26747::Coeffs[0] = 0.0; + Parab2d_Bug26747::Coeffs[1] = 1.0; + Parab2d_Bug26747::Coeffs[2] = 0.0; + Parab2d_Bug26747::Coeffs[3] = 1.0; + Parab2d_Bug26747::Coeffs[4] = -3.0; + Parab2d_Bug26747::Coeffs[5] = 10.0; + + OCC26747_CheckParabola(theDI, theArgVal[1], Standard_False); + + return 0; +} + +//======================================================================= +//function : OCC26747_3 +//purpose : Creates a 2D-parabola for testing +//======================================================================= +static Standard_Integer OCC26747_3(Draw_Interpretor& theDI, + Standard_Integer theNArg, + const char ** theArgVal) +{ + if(theNArg < 2) + { + theDI << "Use: OCC26747_2 result\n"; + return 1; + } + + //Expected parabola: + + // ^ Y + // | + // o | + // o | + // F x o A + // o | + // o | + // | + // <------------------ + // X + + // where (in UCS - User Coordinate System, - which + // is shown in the picture): + // Y-axe is the directrix of the parabola, + // A(0.0, 3.0) is a Vertex of the parabola, + // F(0.0, 3.0) is the focus of the parabola (the Focus + // matches with the Apex). + // + // In WCS (World Coordinate System) these points have coordinates: + // A(0.0, 3.0), F(0.0, 3.0). + // + // Focal length is 0.0, + // Parameter of the parabola is 0.0. + // Equation (in WCS): (y-3)^2=2*p*(-x-0.0), i.e. (y-3)^2=0 (looks like a line y=3) + // A * X^2 + B * (Y^2) + 2*C*(X*Y) + 2*D*X + 2*E*Y + F = 0. + // 0 * X^2 + 1 * (Y^2) + 2*0*(X*Y) + 2*0*X + 2*(-3)*Y + 9 = 0. + + Parab2d_Bug26747::Axes = gp_Ax2d(gp_Pnt2d(0.0, 0.0), gp_Dir2d(0.0, 1.0)); + Parab2d_Bug26747::FocusPoint.SetCoord(0.0, 3.0); + + Parab2d_Bug26747::FocalLength = 0.0; + + Parab2d_Bug26747::VertX = 0.0; + Parab2d_Bug26747::VertY = 3.0; + + Parab2d_Bug26747::Parameter = 0.0; + + Parab2d_Bug26747::Coeffs[0] = 0.0; + Parab2d_Bug26747::Coeffs[1] = 1.0; + Parab2d_Bug26747::Coeffs[2] = 0.0; + Parab2d_Bug26747::Coeffs[3] = 0.0; + Parab2d_Bug26747::Coeffs[4] = -3.0; + Parab2d_Bug26747::Coeffs[5] = 9.0; + + OCC26747_CheckParabola(theDI, theArgVal[1], Standard_False); + + return 0; +} + +#include "Geom2d_BezierCurve.hxx" +#include "Geom2dGcc_QualifiedCurve.hxx" +#include "Geom2dAdaptor_Curve.hxx" +#include "Geom2dAPI_ProjectPointOnCurve.hxx" +#include "Geom2dGcc_Circ2d2TanOn.hxx" +//======================================================================= +//function : OCC27357 +//purpose : +//======================================================================= +static Standard_Integer OCC27357(Draw_Interpretor& theDI, + Standard_Integer, + const char **) +{ + TColgp_Array1OfPnt2d aPoles(1,3); + aPoles.SetValue(1, gp_Pnt2d(0.,0.)); + aPoles.SetValue(2, gp_Pnt2d(0.,1.)); + aPoles.SetValue(3, gp_Pnt2d(6.,0.)); + + Handle(Geom2d_BezierCurve) aCurve1 = new Geom2d_BezierCurve(aPoles); + aPoles.SetValue(2, gp_Pnt2d(0.,1.5)); + Handle(Geom2d_BezierCurve) aCurve2 = new Geom2d_BezierCurve(aPoles); + NCollection_List aDuumyList; + int nP = 100; + for(int i = 0 ; i < nP ; i++){ + Standard_Real u = i / (nP-1.); + gp_Pnt2d aP1; + gp_Vec2d aTangent; + aCurve1->D1(u,aP1,aTangent); + gp_Vec2d aNormal(-aTangent.Y(),aTangent.X()); + Handle(Geom2d_Line) normalLine=new Geom2d_Line(aP1, gp_Dir2d(aNormal)); + Geom2dGcc_QualifiedCurve qualifiedC1(Geom2dAdaptor_Curve(aCurve1),GccEnt_unqualified); + Geom2dGcc_QualifiedCurve qualifiedC2(Geom2dAdaptor_Curve(aCurve2),GccEnt_unqualified); + + try + { + Geom2dAPI_ProjectPointOnCurve projPc1(aP1, aCurve1); + double g1 = projPc1.LowerDistanceParameter(); + Geom2dAPI_ProjectPointOnCurve projPc3(aP1, normalLine); + double g3 = projPc3.LowerDistanceParameter(); + Geom2dGcc_Circ2d2TanOn aCircleBuilder(qualifiedC1,qualifiedC2, + Geom2dAdaptor_Curve(normalLine),1e-9,g1,g1,g3); + aDuumyList.Append(aCircleBuilder.NbSolutions()); + } + catch(Standard_Failure) + { + theDI << "Exception was caught\n"; + } + } + return 0; +} +#include +#include +#include +#include +#include +#include +//======================================================================= +//function : OCC26270 +//purpose : +//======================================================================= +static Standard_Integer OCC26270(Draw_Interpretor& theDI, + Standard_Integer theNArg, + const char **theArgVal) +{ + if (theNArg != 3) + { + theDI << "Usage :" << theArgVal[0] << " shape result\n"; + return 0; + } + TopoDS_Shape aShape = DBRep::Get(theArgVal[1]); + TopExp_Explorer anExp(aShape, TopAbs_EDGE); + TColGeom_SequenceOfCurve aCurveSeq; + for (; anExp.More(); anExp.Next()) + { + Standard_Real f, l; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(anExp.Current()), f, l); + if (!aCurve.IsNull()) + { + aCurve = new Geom_TrimmedCurve(aCurve, f, l); + aCurveSeq.Append(aCurve); + } + } + if (aCurveSeq.Length() > 1) + { + try + { + OCC_CATCH_SIGNALS + GeomFill_NSections aBSurface(aCurveSeq); + Handle(Geom_BSplineSurface) aRes = aBSurface.BSplineSurface(); + if (!aRes.IsNull()) + { + BRepBuilderAPI_MakeFace b_face1(aRes, Precision::Confusion()); + TopoDS_Face bsp_face1 = b_face1.Face(); + DBRep::Set(theArgVal[2], bsp_face1); + } + } + catch (Standard_Failure) + { + theDI << "ERROR: Exception in GeomFill_NSections\n"; + } + } + return 0; +} + +#include "BRepBuilderAPI_MakeWire.hxx" +#include "BRepBuilderAPI_MakeEdge.hxx" +static Standard_Integer OCC27552(Draw_Interpretor&, + Standard_Integer, + const char ** ) +{ + BRep_Builder BB; + TopoDS_Vertex V1, V2, V3; + TopoDS_Edge E1, E2; + BB.MakeVertex(V1, gp_Pnt(0,0,0), 0.1); + BB.MakeVertex(V2, gp_Pnt(5,0,0), 0.1); + BB.MakeVertex(V3, gp_Pnt(10,0,0), 0.1); + E1 = BRepBuilderAPI_MakeEdge(V1, V2).Edge(); + E2 = BRepBuilderAPI_MakeEdge(V2, V3).Edge(); + BRepBuilderAPI_MakeWire MW; + MW.Add(E1); + MW.Add(E2); + TopoDS_Vertex V4, V5, V6, V7; + TopoDS_Edge E3, E4; + BB.MakeVertex(V4, gp_Pnt(10,0+0.05,0), 0.07); + BB.MakeVertex(V5, gp_Pnt(10,0-0.05,0), 0.07); + BB.MakeVertex(V6, gp_Pnt(10,0+2,0), 0.07); + BB.MakeVertex(V7, gp_Pnt(10,0-2,0), 0.07); + E3 = BRepBuilderAPI_MakeEdge(V4, V6).Edge(); + E4 = BRepBuilderAPI_MakeEdge(V5, V7).Edge(); + TopTools_ListOfShape LLE; + LLE.Append(E3); + LLE.Append(E4); + MW.Add(LLE); + TopoDS_Shape W = MW.Wire(); + DBRep::Set("outw", W); + + return 0; +} + +#include +static Standard_Integer OCC27875(Draw_Interpretor& theDI, + Standard_Integer theNArg, + const char ** theArgVal) +{ + if (theNArg < 2) + { + theDI << "Use: OCC27875 curve\n"; + } + + TColGeom_SequenceOfCurve aNC(new NCollection_IncAllocator()); + + const Handle(Geom_Curve) aC = Handle(Geom_Curve)::DownCast(DrawTrSurf::Get(theArgVal[1])); + + aNC.Append(aC); + + GeomFill_NSections aNS(aNC); + + if (aNS.BSplineSurface().IsNull()) + { + theDI << "GeomFill_NSections is not done.\n"; + } + + return 0; +} + + +#include +#include +#include +#include +#include +static Standard_Integer OCC28389(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +{ + if (argc < 20) { + di << "Use: OCC28389 Doc label nb_shapes nb_GDT nb_planes name type pp_x pp_y pp_z vd_x vd_y vd_z ud_x ud_y ud_z zoom width height"; + return 1; + } + Handle(TDocStd_Document) aDoc; + DDocStd::GetDocument(argv[1], aDoc); + if (aDoc.IsNull()) { + di << "Error: Wrong document"; + return 1; + } + Handle(XCAFDoc_ViewTool) aViewTool = XCAFDoc_DocumentTool::ViewTool(aDoc->Main()); + + TDF_Label aLabel; + TDF_Tool::Label(aDoc->GetData(), argv[2], aLabel); + if (aLabel.IsNull()) { + di << "Error: Wrong label"; + return 1; + } + Handle(XCAFDoc_View) aView; + if (!aLabel.FindAttribute(XCAFDoc_View::GetID(), aView)) { + di << "Error: Wrong label"; + return 1; + } + Handle(XCAFView_Object) anObj = aView->GetObject(); + if (anObj.IsNull()) { + di << "Error: Wrong label"; + return 1; + } + + Standard_Boolean isOK = Standard_True; + // check links + Standard_Integer nbShapes = Draw::Atoi(argv[3]); + Standard_Integer nbGDTs = Draw::Atoi(argv[4]); + Standard_Integer nbPlanes = Draw::Atoi(argv[5]); + TDF_LabelSequence aSequence; + aViewTool->GetRefShapeLabel(aLabel, aSequence); + if (aSequence.Length() != nbShapes) + isOK = Standard_False; + aSequence.Clear(); + aViewTool->GetRefGDTLabel(aLabel, aSequence); + if (aSequence.Length() != nbGDTs) + isOK = Standard_False; + aSequence.Clear(); + aViewTool->GetRefClippingPlaneLabel(aLabel, aSequence); + if (aSequence.Length() != nbPlanes) + isOK = Standard_False; + if (!isOK) { + di << "Error: Wrong references"; + return 1; + } + + if (anObj->Name()->IsDifferent(new TCollection_HAsciiString(argv[6]))) { + di << "Error: Wrong name"; + return 1; + } + + XCAFView_ProjectionType aType = XCAFView_ProjectionType_NoCamera; + if (argv[7][0] == 'p') + aType = XCAFView_ProjectionType_Parallel; + else if (argv[7][0] == 'c') + aType = XCAFView_ProjectionType_Central; + + if (anObj->Type()!= aType) { + di << "Error: Wrong type"; + return 1; + } + + gp_Pnt aPP(Draw::Atof(argv[8]), Draw::Atof(argv[9]), Draw::Atof(argv[10])); + if (aPP.Distance(anObj->ProjectionPoint()) > Precision::Confusion()) { + di << "Error: Wrong projection point"; + return 1; + } + + gp_Dir aVD(Draw::Atof(argv[11]), Draw::Atof(argv[12]), Draw::Atof(argv[13])); + if (!aVD.IsEqual(anObj->ViewDirection(), Precision::Angular())) { + di << "Error: Wrong view direction"; + return 1; + } + + gp_Dir aUD(Draw::Atof(argv[14]), Draw::Atof(argv[15]), Draw::Atof(argv[16])); + if (!aUD.IsEqual(anObj->UpDirection(), Precision::Angular())) { + di << "Error: Wrong up direction"; + return 1; + } + + if (fabs(anObj->ZoomFactor() - Draw::Atof(argv[17])) > Precision::Confusion()) { + di << "Error: Wrong zoom factor"; + return 1; + } + + if (fabs(anObj->WindowHorizontalSize() - Draw::Atof(argv[18])) > Precision::Confusion()) + isOK = Standard_False; + if (fabs(anObj->WindowVerticalSize() - Draw::Atof(argv[19])) > Precision::Confusion()) + isOK = Standard_False; + if (!isOK) { + di << "Error: Wrong Window size"; + return 1; + } + + di << argv[2] << " OK"; + return 0; +} + +#include +#include +#include +#include +#include +#include +#include + +static Standard_Integer OCC28594(Draw_Interpretor& di, Standard_Integer argc, const char** argv) +{ + if (argc != 3) + { + di << "Usage :" << argv[0] << " curve_with_scale curve_without_scale\n"; + return 0; + } + Handle(TColgp_HArray1OfPnt2d) points_2d = new TColgp_HArray1OfPnt2d(1, 6); + (*points_2d)(1) = gp_Pnt2d(-30.4, 8); + (*points_2d)(2) = gp_Pnt2d(-16.689912, 17.498217); + (*points_2d)(3) = gp_Pnt2d(-23.803064, 24.748543); + (*points_2d)(4) = gp_Pnt2d(-16.907466, 32.919615); + (*points_2d)(5) = gp_Pnt2d(-8.543829, 26.549421); + (*points_2d)(6) = gp_Pnt2d(0, 39.200000); + + TColgp_Array1OfVec2d tangent_2d(1, 6); + (tangent_2d)(1) = gp_Vec2d(0.3, 0.4); + (tangent_2d)(2) = gp_Vec2d(0, 0); + (tangent_2d)(3) = gp_Vec2d(0, 0); + (tangent_2d)(4) = gp_Vec2d(0, 0); + (tangent_2d)(5) = gp_Vec2d(0, 0); + (tangent_2d)(6) = gp_Vec2d(1, 0); + + Handle(TColStd_HArray1OfBoolean) tangent_flags = new TColStd_HArray1OfBoolean(1, 6); + (*tangent_flags)(1) = true; + (*tangent_flags)(2) = false; + (*tangent_flags)(3) = false; + (*tangent_flags)(4) = false; + (*tangent_flags)(5) = false; + (*tangent_flags)(6) = true; + + Geom2dAPI_Interpolate interp_2d_with_scale(points_2d, Standard_False, Precision::Confusion()); + interp_2d_with_scale.Load(tangent_2d, tangent_flags); + interp_2d_with_scale.Perform(); + Handle(Geom2d_BSplineCurve) curve_2d_with_scale = interp_2d_with_scale.Curve(); + + Geom2dAPI_Interpolate interp_2d_without_scale(points_2d, Standard_False, Precision::Confusion()); + interp_2d_without_scale.Load(tangent_2d, tangent_flags, Standard_False); + interp_2d_without_scale.Perform(); + Handle(Geom2d_BSplineCurve) curve_2d_without_scale = interp_2d_without_scale.Curve(); + + DrawTrSurf::Set(argv[1], curve_2d_with_scale); + DrawTrSurf::Set(argv[2], curve_2d_without_scale); + return 0; +} + +static Standard_Integer OCC28784(Draw_Interpretor&, Standard_Integer argc, const char** argv) +{ + if (argc < 3) + return 1; + + TopoDS_Shape aShape = DBRep::Get(argv[2]); + if (aShape.IsNull()) + return 1; + + gp_Ax2 aPlane (gp::Origin(), gp::DX(), -gp::DZ()); + HLRAlgo_Projector aProjector(aPlane); + + Handle(HLRBRep_PolyAlgo) aHLR = new HLRBRep_PolyAlgo(aShape); + aHLR->Projector(aProjector); + aHLR->Update(); + + HLRBRep_PolyHLRToShape aHLRtoShape; + aHLRtoShape.Update(aHLR); + + TopoDS_Shape aHidden = aHLRtoShape.HCompound(); + + DBRep::Set(argv[1], aHidden); + + return 0; +} + +static Standard_Integer OCC28829 (Draw_Interpretor&, Standard_Integer, const char**) +{ + // do something that causes FPE exception + std::cout << "sqrt(-1) = " << sqrt (-1.) << std::endl; + return 0; +} + +#include +#include +#include +#include +#include +#include + +#ifdef max + #undef max +#endif + +static Standard_Integer OCC28887 (Draw_Interpretor&, Standard_Integer theNbArgs, const char** theArgVec) +{ + if (theNbArgs < 3) + { + std::cout << "Syntax error: wrong number of arguments!\n"; + return 1; + } + + const TCollection_AsciiString aFilePath (theArgVec[1]); + const TCollection_AsciiString aName (theArgVec[2]); + Handle(NCollection_Buffer) aBuffer; + { + std::ifstream aFile; + OSD_OpenStream (aFile, aFilePath.ToCString(), std::ios::binary | std::ios::in); + if (!aFile.is_open()) + { + std::cout << "Error: input file '" << aFilePath << "' cannot be read\n"; + return 1; + } + aFile.seekg (0, std::ios_base::end); + const int64_t aFileLength = int64_t (aFile.tellg()); + if (aFileLength > int64_t (std::numeric_limits::max()) + || aFileLength < 1) + { + std::cout << "Error: input file '" << aFilePath << "' is too large\n"; + return 1; + } + aFile.seekg (0, std::ios_base::beg); + + aBuffer = new NCollection_Buffer (NCollection_BaseAllocator::CommonBaseAllocator()); + if (!aBuffer->Allocate (size_t(aFileLength))) + { + std::cout << "Error: memory allocation (" << aFileLength << ") has failed\n"; + return 1; + } + + aFile.read ((char* )aBuffer->ChangeData(), aBuffer->Size()); + if (!aFile.good()) + { + std::cout << "Error: input file '" << aFilePath << "' reading failure\n"; + return 1; + } + } + + Standard_ArrayStreamBuffer aStreamBuffer ((const char* )aBuffer->ChangeData(), aBuffer->Size()); + std::istream aStream (&aStreamBuffer); + // just play with seeking + aStream.seekg (0, std::ios_base::end); + aStream.seekg (0, std::ios_base::beg); + if (aFilePath.EndsWith (".brep") + || aFilePath.EndsWith (".rle")) + { + TopoDS_Shape aShape; + BRep_Builder aBuilder; + BRepTools::Read (aShape, aStream, aBuilder); + DBRep::Set (aName.ToCString(), aShape); + } + else + { + Handle(TDocStd_Document) aDoc; + Handle(TDocStd_Application) anApp = DDocStd::GetApplication(); + Standard_CString aNameVar = aName.ToCString(); + if (DDocStd::GetDocument (aNameVar, aDoc, Standard_False)) + { + std::cout << "Error: document with name " << aName << " already exists\n"; + return 1; + } + + if (anApp->Open (aStream, aDoc) != PCDM_RS_OK) + { + std::cout << "Error: cannot open XDE document\n"; + return 1; + } + + Handle(DDocStd_DrawDocument) aDrawDoc = new DDocStd_DrawDocument (aDoc); + TDataStd_Name::Set (aDoc->GetData()->Root(), aName.ToCString()); + Draw::Set (aName.ToCString(), aDrawDoc); + } + + return 0; +} + +static Standard_Integer OCC28131 (Draw_Interpretor&, Standard_Integer theNbArgs, const char** theArgVec) +{ + if (theNbArgs != 2) + { + std::cerr << "Error: wrong number of arguments" << std::endl; + return 1; + } + + double height = 8.5; + gp_Pnt JiZhunXian2_v0 = gp_Pnt(-17.6, 0.0, 0.0); + gp_Pnt JiZhunXian2_v1 = gp_Pnt(0, 32.8, 0.0); + + // Outline + TColgp_Array1OfPnt outer_e_bzr_geom_v(1, 4); + { + outer_e_bzr_geom_v(1) = JiZhunXian2_v0; + outer_e_bzr_geom_v(4) = JiZhunXian2_v1; + + Standard_Real ratio1 = 5.4 / 13.2; + outer_e_bzr_geom_v(2) = gp_Pnt(outer_e_bzr_geom_v(1).X(), ratio1*outer_e_bzr_geom_v(4).Y(), 0); + Standard_Real ratio2 = 6.0 / 6.8; + outer_e_bzr_geom_v(3) = gp_Pnt(ratio2*outer_e_bzr_geom_v(1).X(), outer_e_bzr_geom_v(4).Y(), 0); + } + + Handle(Geom_BezierCurve) outer_e_bzr_geom = new Geom_BezierCurve(outer_e_bzr_geom_v); + Handle(Geom_BSplineCurve) outer_e_bsp_geom = GeomConvert::CurveToBSplineCurve(outer_e_bzr_geom); + TopoDS_Edge outer_e = BRepBuilderAPI_MakeEdge(outer_e_bsp_geom); + + Handle(Geom_BSplineCurve) curve1; + { + Handle(TColgp_HArray1OfPnt2d) harray = new TColgp_HArray1OfPnt2d(1, 2); // sizing harray + harray->SetValue(1, gp_Pnt2d(-JiZhunXian2_v1.Y(), 0)); + harray->SetValue(2, gp_Pnt2d(0, height + height / 2)); + + Geom2dAPI_Interpolate anInterpolation(harray, Standard_False, 1e-6); + + gp_Vec2d vtangent1(0, 1); + gp_Vec2d vtangent2(1, 0); + anInterpolation.Load(vtangent1, vtangent2); + anInterpolation.Perform(); + + Handle(Geom2d_BSplineCurve) c = anInterpolation.Curve(); + + gp_Pln pln(gp_Ax3(gp_Pnt(), gp_Dir(1, 0, 0), gp_Dir(0, -1, 0))); + + Handle(Geom_BSplineCurve) c3d = Handle(Geom_BSplineCurve)::DownCast(GeomAPI::To3d(c, pln)); + curve1 = c3d; + } + + Handle(Geom_BSplineCurve) curve2; + { + Handle(TColgp_HArray1OfPnt2d) harray = new TColgp_HArray1OfPnt2d(1, 3); // sizing harray + harray->SetValue(1, gp_Pnt2d(-JiZhunXian2_v0.X(), 0)); + harray->SetValue(2, gp_Pnt2d(-JiZhunXian2_v0.X() - 2.6, height)); + harray->SetValue(3, gp_Pnt2d(0, height + height / 2)); + + Geom2dAPI_Interpolate anInterpolation(harray, Standard_False, 1e-6); + anInterpolation.Perform(); + + Handle(Geom2d_BSplineCurve) c = anInterpolation.Curve(); + gp_Pln pln(gp_Ax3(gp_Pnt(), gp_Dir(0, -1, 0), gp_Dir(-1, 0, 0))); + Handle(Geom_BSplineCurve) c3d = Handle(Geom_BSplineCurve)::DownCast(GeomAPI::To3d(c, pln)); + curve2 = c3d; + } + + ////////////////////////////////////// + GeomFill_BSplineCurves fill2; + fill2.Init(outer_e_bsp_geom, curve1, curve2, GeomFill_CoonsStyle); + + const Handle(Geom_BSplineSurface)& surf_geom = fill2.Surface(); + + TopoDS_Shape filled_face = BRepBuilderAPI_MakeFace(surf_geom, 0); + + DBRep::Set (theArgVec[1], filled_face); + +/* + /////////////////////////////////////////////////////////////////////// + TopoDS_Solid first_solid; + { + BRepOffset_MakeOffset myOffsetShape(filled_face, -offset_thick, 1e-4, + BRepOffset_Skin, //Mode + Standard_False, //Intersection + Standard_False, //SelfInter + GeomAbs_Intersection, //Join + Standard_True, //Thickening + Standard_False //RemoveIntEdges + ); //RemoveInvalidFaces + first_solid = TopoDS::Solid(myOffsetShape.Shape()); + } +*/ + return 0; +} + +#include +#include +static Standard_Integer myCall(Draw_Interpretor&, Standard_Integer theNbArgs, const char** theArgVec) +{ + TopoDS_Wire extrudeWire = TopoDS::Wire(DBRep::Get(theArgVec[2])); + TopoDS_Wire toolWire = TopoDS::Wire(DBRep::Get(theArgVec[3])); + + // ################################ Check and Fix Wire Gaps ######################################### + if (1) + { + ShapeFix_Wireframe fix_tool(extrudeWire); + fix_tool.ModeDropSmallEdges() = Standard_True; + fix_tool.SetPrecision(Precision::Confusion()); //yes! + fix_tool.FixSmallEdges(); + fix_tool.FixWireGaps(); + extrudeWire = TopoDS::Wire(fix_tool.Shape()); + } + + // ################################ Extrude tool ######################################### + BRepOffsetAPI_MakeEvolved mkEvolved = BRepOffsetAPI_MakeEvolved(extrudeWire, toolWire, GeomAbs_Arc, Standard_False, Standard_True, Standard_False, Standard_True, 0); + + DBRep::Set(theArgVec[1], mkEvolved.Shape()); + + return 0; +} + +//======================================================================= +//function : FindGaps +//purpose : +//======================================================================= +static Standard_Integer FindGaps(Draw_Interpretor& theDI, Standard_Integer theNArg, const char** theArgV) +{ + if (theNArg < 3) + { + theDI << "Use: " << theArgV[0] << " result wire\n"; + return 1; + } + + const TopoDS_Wire aWir = TopoDS::Wire(DBRep::Get(theArgV[2])); + + TopTools_IndexedDataMapOfShapeListOfShape aMapVE; + TopExp::MapShapesAndAncestors(aWir, TopAbs_VERTEX, TopAbs_EDGE, aMapVE); + + Standard_Real aMaxDist = RealFirst(); + + for (Standard_Integer i = 1; i <= aMapVE.Extent(); i++) + { + const TopoDS_Vertex &aV = TopoDS::Vertex(aMapVE.FindKey(i)); + + TopTools_ListOfShape aLE = aMapVE.FindFromIndex(i); + + const TopoDS_Edge anE1 = TopoDS::Edge(aLE.First()); + const TopoDS_Edge anE2 = TopoDS::Edge(aLE.Last()); + + const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2); + + const Standard_Real aPrm1 = BRep_Tool::Parameter(aV, anE1); + const Standard_Real aPrm2 = BRep_Tool::Parameter(aV, anE2); + + gp_Pnt aP1, aP2; + anAC1.D0(aPrm1, aP1); + anAC2.D0(aPrm2, aP2); + + char aBuff[100]; + Sprintf(aBuff, "%sv%d", theArgV[1], i); + DBRep::Set(aBuff, aV); + + const Standard_Real aDist = aP1.Distance(aP2); + aMaxDist = Max(aMaxDist, aDist); + + theDI << aBuff << ": Dist = " << aDist << "\n"; + } + + theDI << "Max. gap is " << aMaxDist << "\n"; + + return 0; +} + +//======================================================================= +//function : VEProcess +//purpose : +//======================================================================= +static Standard_Integer VEProcess(Draw_Interpretor& theDI, Standard_Integer theNArg, const char** theArgV) +{ + if (theNArg < 3) + { + theDI << "Use: " << theArgV[0] << " result wire\n"; + return 1; + } + + const TopoDS_Wire aWir = TopoDS::Wire(DBRep::Get(theArgV[2])); + + TopTools_IndexedDataMapOfShapeListOfShape aMapVE; + TopExp::MapShapesAndAncestors(aWir, TopAbs_VERTEX, TopAbs_EDGE, aMapVE); + + for (Standard_Integer i = 1; i <= aMapVE.Extent(); i++) + { + const TopoDS_Vertex &aV = TopoDS::Vertex(aMapVE.FindKey(i)); + + TopTools_ListOfShape aLE = aMapVE.FindFromIndex(i); + + const TopoDS_Edge anE1 = TopoDS::Edge(aLE.First()); + const TopoDS_Edge anE2 = TopoDS::Edge(aLE.Last()); + + const BRepAdaptor_Curve anAC1(anE1), anAC2(anE2); + + const Standard_Real aPrm1 = BRep_Tool::Parameter(aV, anE1); + const Standard_Real aPrm2 = BRep_Tool::Parameter(aV, anE2); + + gp_Pnt aP; + gp_Vec aT1, aT2; + anAC1.D1(aPrm1, aP, aT1); + anAC2.D1(aPrm2, aP, aT2); + + Standard_Real anAngle = aT1.Angle(aT2); + + if (anAngle > M_PI_2) + anAngle = M_PI - anAngle; + + char aBuff[100]; + Sprintf(aBuff, "%sv%d", theArgV[1], i); + DBRep::Set(aBuff, aV); + + theDI << aBuff << " (" << BRep_Tool::Tolerance(aV) << "): A = " << anAngle << "\n"; + } + + return 0; +} + + +void QABugs::Commands_20(Draw_Interpretor& theCommands) { + const char *group = "QABugs"; + + theCommands.Add ("OCC26675_1", "OCC26675_1 result", __FILE__, SurfaceGenOCC26675_1, group); + theCommands.Add ("OCC24836", "OCC24836", __FILE__, OCC24836, group); + theCommands.Add("OCC27021", "OCC27021", __FILE__, OCC27021, group); + theCommands.Add("OCC27235", "OCC27235", __FILE__, OCC27235, group); + theCommands.Add("OCC26930", "OCC26930", __FILE__, OCC26930, group); + theCommands.Add("OCC27466", "OCC27466", __FILE__, OCC27466, group); + theCommands.Add("OCC27341", + "OCC27341 res shape axo/top/bottom/front/back/left/right", + __FILE__, OCC27341, group); + theCommands.Add ("OCC26747_1", "OCC26747_1 result", __FILE__, OCC26747_1, group); + theCommands.Add ("OCC26747_2", "OCC26747_2 result", __FILE__, OCC26747_2, group); + theCommands.Add ("OCC26747_3", "OCC26747_3 result", __FILE__, OCC26747_3, group); + theCommands.Add ("OCC27357", "OCC27357", __FILE__, OCC27357, group); + theCommands.Add("OCC26270", "OCC26270 shape result", __FILE__, OCC26270, group); + theCommands.Add ("OCC27552", "OCC27552", __FILE__, OCC27552, group); + theCommands.Add("OCC27875", "OCC27875 curve", __FILE__, OCC27875, group); + theCommands.Add("OCC28389", "OCC28389", __FILE__, OCC28389, group); + theCommands.Add("OCC28594", "OCC28594", __FILE__, OCC28594, group); + theCommands.Add("OCC28784", "OCC28784 result shape", __FILE__, OCC28784, group); + theCommands.Add("OCC28829", "OCC28829: perform invalid FPE operation", __FILE__, OCC28829, group); + theCommands.Add("OCC28887", + "OCC28887 filePath result" + "\n\t\t: Check interface for reading BRep from memory.", + __FILE__, OCC28887, group); + theCommands.Add("OCC28131", "OCC28131 name: creates face problematic for offset", __FILE__, OCC28131, group); + + theCommands.Add("myCall", "myCall result spine profile", __FILE__, myCall, group); + + theCommands.Add("findgaps", "findgaps result wire", __FILE__, FindGaps, group); + theCommands.Add("veproc", "veproc result wire", __FILE__, VEProcess, group); + + return; +} diff --git a/src/DrawResources/CheckCommands.tcl b/src/DrawResources/CheckCommands.tcl index b9acbb100d..5a2b24f2a7 100644 --- a/src/DrawResources/CheckCommands.tcl +++ b/src/DrawResources/CheckCommands.tcl @@ -595,6 +595,14 @@ proc checkprops {shape args} { if { $m == 0 } { puts "Error : The command is not valid. The $prop is 0." } + # Provide comparation with negative value + if { [expr $mass*$m ] < 0.0 } { + # Value and expected value have different sign + puts "Error : The $prop of result shape is $m" + } else { + set mass [expr abs($mass)] + set m [expr abs($m)] + } if { $mass > 0 } { puts "The expected $prop is $mass" } diff --git a/src/Font/Font_BRepFont.cxx b/src/Font/Font_BRepFont.cxx index ff3e47e62d..8f8dc94a7b 100755 --- a/src/Font/Font_BRepFont.cxx +++ b/src/Font/Font_BRepFont.cxx @@ -66,9 +66,10 @@ namespace //! Auxiliary method to convert FT_Vector to gp_XY static gp_XY readFTVec (const FT_Vector& theVec, - const Standard_Real theScaleUnits) + const Standard_Real theScaleUnits, + const Standard_Real theWidthScaling = 1.0) { - return gp_XY (theScaleUnits * Standard_Real(theVec.x) / 64.0, theScaleUnits * Standard_Real(theVec.y) / 64.0); + return gp_XY (theScaleUnits * Standard_Real(theVec.x) * theWidthScaling / 64.0, theScaleUnits * Standard_Real(theVec.y) / 64.0); } } @@ -265,7 +266,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar, TopLoc_Location aLoc; TopoDS_Face aFaceDraft; - myBuilder.MakeFace (aFaceDraft, mySurface, myPrecision); + TopoDS_Compound aFaceCompDraft; // Get orientation is useless since it doesn't retrieve any in-font information and just computes orientation. // Because it fails in some cases - leave this to ShapeFix. @@ -277,7 +278,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar, const short anEndIndex = anOutline.contours[aContour]; const short aPntsNb = (anEndIndex - aStartIndex) + 1; aStartIndex = anEndIndex + 1; - if (aPntsNb < 3) + if (aPntsNb < 3 && !myIsSingleLine) { // closed contour can not be constructed from < 3 points continue; @@ -286,10 +287,11 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar, BRepBuilderAPI_MakeWire aWireMaker; gp_XY aPntPrev; - gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits); - gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits); + gp_XY aPntCurr = readFTVec (aPntList[aPntsNb - 1], myScaleUnits, myWidthScaling); + gp_XY aPntNext = readFTVec (aPntList[0], myScaleUnits, myWidthScaling); - Standard_Integer aLinePnts = (FT_CURVE_TAG(aTags[aPntsNb - 1]) == FT_Curve_Tag_On) ? 1 : 0; + bool isLineSeg = !myIsSingleLine + && FT_CURVE_TAG(aTags[aPntsNb - 1]) == FT_Curve_Tag_On; gp_XY aPntLine1 = aPntCurr; // see http://freetype.sourceforge.net/freetype2/docs/glyphs/glyphs-6.html @@ -298,15 +300,15 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar, { aPntPrev = aPntCurr; aPntCurr = aPntNext; - aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits); + aPntNext = readFTVec (aPntList[(aPntId + 1) % aPntsNb], myScaleUnits, myWidthScaling); // process tags if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_On) { - if (aLinePnts < 1) + if (!isLineSeg) { aPntLine1 = aPntCurr; - aLinePnts = 1; + isLineSeg = true; continue; } @@ -315,7 +317,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar, if (aLen <= myPrecision) { aPntLine1 = aPntCurr; - aLinePnts = 1; + isLineSeg = true; continue; } @@ -339,7 +341,7 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar, } else if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_Conic) { - aLinePnts = 0; + isLineSeg = false; gp_XY aPntPrev2 = aPntPrev; gp_XY aPntNext2 = aPntNext; @@ -378,11 +380,11 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar, else if (FT_CURVE_TAG(aTags[aPntId]) == FT_Curve_Tag_Cubic && FT_CURVE_TAG(aTags[(aPntId + 1) % aPntsNb]) == FT_Curve_Tag_Cubic) { - aLinePnts = 0; + isLineSeg = false; my4Poles.SetValue (1, aPntPrev); my4Poles.SetValue (2, aPntCurr); my4Poles.SetValue (3, aPntNext); - my4Poles.SetValue (4, gp_Pnt2d(readFTVec (aPntList[(aPntId + 2) % aPntsNb], myScaleUnits))); + my4Poles.SetValue (4, gp_Pnt2d(readFTVec (aPntList[(aPntId + 2) % aPntsNb], myScaleUnits, myWidthScaling))); Handle(Geom2d_BezierCurve) aBezier = new Geom2d_BezierCurve (my4Poles); if (myIsCompositeCurve) { @@ -411,7 +413,8 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar, const gp_Pnt2d aFirstPnt = aDraft2d->StartPoint(); const gp_Pnt2d aLastPnt = aDraft2d->EndPoint(); - if (!aFirstPnt.IsEqual (aLastPnt, myPrecision)) + if (!myIsSingleLine + && !aFirstPnt.IsEqual (aLastPnt, myPrecision)) { Handle(Geom2d_TrimmedCurve) aLine = GCE2d_MakeSegment (aLastPnt, aFirstPnt); myConcatMaker.Add (aLine, myPrecision); @@ -438,7 +441,8 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar, TopExp::Vertices (aWireMaker.Wire(), aFirstV, aLastV); gp_Pnt aFirstPoint = BRep_Tool::Pnt (aFirstV); gp_Pnt aLastPoint = BRep_Tool::Pnt (aLastV); - if (!aFirstPoint.IsEqual (aLastPoint, myPrecision)) + if (!myIsSingleLine + && !aFirstPoint.IsEqual (aLastPoint, myPrecision)) { aWireMaker.Add (BRepLib_MakeEdge (aFirstV, aLastV)); } @@ -450,31 +454,64 @@ Standard_Boolean Font_BRepFont::renderGlyph (const Standard_Utf32Char theChar, } TopoDS_Wire aWireDraft = aWireMaker.Wire(); - //if (anOrient == FT_ORIENTATION_FILL_LEFT) - //{ - // According to the TrueType specification, clockwise contours must be filled - aWireDraft.Reverse(); - //} - myBuilder.Add (aFaceDraft, aWireDraft); + if (!myIsSingleLine) + { + //if (anOrient == FT_ORIENTATION_FILL_LEFT) + //{ + // According to the TrueType specification, clockwise contours must be filled + aWireDraft.Reverse(); + //} + if (aFaceDraft.IsNull()) + { + myBuilder.MakeFace (aFaceDraft, mySurface, myPrecision); + } + myBuilder.Add (aFaceDraft, aWireDraft); + } + else + { + if (aFaceCompDraft.IsNull()) + { + myBuilder.MakeCompound (aFaceCompDraft); + } + myBuilder.Add (aFaceCompDraft, aWireDraft); + } } - myFixer.Init (aFaceDraft); - myFixer.Perform(); - theShape = myFixer.Result(); - if (!theShape.IsNull() - && theShape.ShapeType() != TopAbs_FACE) + if (!aFaceDraft.IsNull()) { - // shape fix can not fix orientation within the single call - TopoDS_Compound aComp; - myBuilder.MakeCompound (aComp); - for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next()) + myFixer.Init (aFaceDraft); + myFixer.Perform(); + TopoDS_Shape aFixResult = myFixer.Result(); + if (!aFixResult.IsNull() + && aFixResult.ShapeType() != TopAbs_FACE) + { + // shape fix can not fix orientation within the single call + if (aFaceCompDraft.IsNull()) + { + myBuilder.MakeCompound (aFaceCompDraft); + } + for (TopExp_Explorer aFaceIter (aFixResult, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next()) + { + TopoDS_Face aFace = TopoDS::Face (aFaceIter.Current()); + myFixer.Init (aFace); + myFixer.Perform(); + myBuilder.Add (aFaceCompDraft, myFixer.Result()); + } + theShape = aFaceCompDraft; + } + else if (!aFaceCompDraft.IsNull()) { - TopoDS_Face aFace = TopoDS::Face (aFaceIter.Current()); - myFixer.Init (aFace); - myFixer.Perform(); - myBuilder.Add (aComp, myFixer.Result()); + myBuilder.Add (aFaceCompDraft, aFixResult); + theShape = aFaceCompDraft; } - theShape = aComp; + else + { + theShape = aFixResult; + } + } + else if (!aFaceCompDraft.IsNull()) + { + theShape = aFaceCompDraft; } myCache.Bind (theChar, theShape); diff --git a/src/Font/Font_FTFont.cxx b/src/Font/Font_FTFont.cxx index b51cac3f8c..6a967728bd 100755 --- a/src/Font/Font_FTFont.cxx +++ b/src/Font/Font_FTFont.cxx @@ -29,12 +29,14 @@ IMPLEMENT_STANDARD_RTTIEXT(Font_FTFont,Standard_Transient) // purpose : // ======================================================================= Font_FTFont::Font_FTFont (const Handle(Font_FTLibrary)& theFTLib) -: myFTLib (theFTLib), - myFTFace (NULL), - myPointSize (0U), - myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL), - myKernAdvance(new FT_Vector()), - myUChar (0U) +: myFTLib (theFTLib), + myFTFace (NULL), + myPointSize (0U), + myWidthScaling(1.0), + myLoadFlags (FT_LOAD_NO_HINTING | FT_LOAD_TARGET_NORMAL), + myIsSingleLine(false), + myKernAdvance (new FT_Vector()), + myUChar (0U) { if (myFTLib.IsNull()) { @@ -118,9 +120,12 @@ bool Font_FTFont::Init (const NCollection_String& theFontName, { Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance(); const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theFontName.ToCString()); - Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize); - return !aRequestedFont.IsNull() - && Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution); + if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, theFontAspect, thePointSize)) + { + myIsSingleLine = aRequestedFont->IsSingleStrokeFont(); + return Font_FTFont::Init (aRequestedFont->FontPath()->ToCString(), thePointSize, theResolution); + } + return false; } // ======================================================================= @@ -263,12 +268,19 @@ float Font_FTFont::AdvanceX (const Standard_Utf32Char theUCharNext) return 0.0f; } - if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0 - || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0) + FT_Pos aKerningX = 0; + if (theUCharNext != 0 + && FT_HAS_KERNING (myFTFace) != 0) { - return fromFTPoints (myFTFace->glyph->advance.x); + const FT_UInt aCharCurr = FT_Get_Char_Index (myFTFace, myUChar); + const FT_UInt aCharNext = FT_Get_Char_Index (myFTFace, theUCharNext); + if (aCharCurr != 0 && aCharNext != 0 + && FT_Get_Kerning (myFTFace, aCharCurr, aCharNext, FT_KERNING_UNFITTED, myKernAdvance) == 0) + { + aKerningX = myKernAdvance->x; + } } - return fromFTPoints (myKernAdvance->x + myFTFace->glyph->advance.x); + return myWidthScaling * fromFTPoints (myFTFace->glyph->advance.x + aKerningX); } // ======================================================================= @@ -282,12 +294,19 @@ float Font_FTFont::AdvanceY (const Standard_Utf32Char theUCharNext) return 0.0f; } - if (FT_HAS_KERNING (myFTFace) == 0 || theUCharNext == 0 - || FT_Get_Kerning (myFTFace, myUChar, theUCharNext, FT_KERNING_UNFITTED, myKernAdvance) != 0) + FT_Pos aKerningY = 0; + if (theUCharNext != 0 + && FT_HAS_KERNING (myFTFace) != 0) { - return fromFTPoints (myFTFace->glyph->advance.y); + const FT_UInt aCharCurr = FT_Get_Char_Index (myFTFace, myUChar); + const FT_UInt aCharNext = FT_Get_Char_Index (myFTFace, theUCharNext); + if (aCharCurr != 0 && aCharNext != 0 + && FT_Get_Kerning (myFTFace, aCharCurr, aCharNext, FT_KERNING_UNFITTED, myKernAdvance) == 0) + { + aKerningY = myKernAdvance->y; + } } - return fromFTPoints (myKernAdvance->y + myFTFace->glyph->advance.y); + return fromFTPoints (myFTFace->glyph->advance.y + aKerningY); } // ======================================================================= diff --git a/src/Font/Font_FTFont.hxx b/src/Font/Font_FTFont.hxx index 4d500fe0b0..8409aad6fa 100755 --- a/src/Font/Font_FTFont.hxx +++ b/src/Font/Font_FTFont.hxx @@ -73,6 +73,13 @@ public: const unsigned int thePointSize, const unsigned int theResolution); + //! Return TRUE if this is single-stroke (one-line) font, FALSE by default. + //! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software. + bool IsSingleStrokeFont() const { return myIsSingleLine; } + + //! Set if this font should be rendered as single-stroke (one-line). + void SetSingleStrokeFont (bool theIsSingleLine) { myIsSingleLine = theIsSingleLine; } + //! Release currently loaded font. Standard_EXPORT virtual void Release(); @@ -100,6 +107,13 @@ public: return myPointSize; } + //! Setup glyph scaling along X-axis. + //! By default glyphs are not scaled (scaling factor = 1.0) + void SetWidthScaling (const float theScaleFactor) + { + myWidthScaling = theScaleFactor; + } + //! Compute advance to the next character with kerning applied when applicable. //! Assuming text rendered horizontally. Standard_EXPORT float AdvanceX (const Standard_Utf32Char theUCharNext); @@ -154,15 +168,17 @@ protected: protected: - Handle(Font_FTLibrary) myFTLib; //!< handle to the FT library object - FT_Face myFTFace; //!< FT face object - NCollection_String myFontPath; //!< font path - unsigned int myPointSize; //!< point size set by FT_Set_Char_Size - int32_t myLoadFlags; //!< default load flags - - Image_PixMap myGlyphImg; //!< cached glyph plane - FT_Vector* myKernAdvance; //!< buffer variable - Standard_Utf32Char myUChar; //!< currently loaded unicode character + Handle(Font_FTLibrary) myFTLib; //!< handle to the FT library object + FT_Face myFTFace; //!< FT face object + NCollection_String myFontPath; //!< font path + unsigned int myPointSize; //!< point size set by FT_Set_Char_Size + float myWidthScaling; //!< scale glyphs along X-axis + int32_t myLoadFlags; //!< default load flags + bool myIsSingleLine; //!< single stroke font flag, FALSE by default + + Image_PixMap myGlyphImg; //!< cached glyph plane + FT_Vector* myKernAdvance; //!< buffer variable + Standard_Utf32Char myUChar; //!< currently loaded unicode character public: diff --git a/src/Font/Font_FontMgr.cxx b/src/Font/Font_FontMgr.cxx index 65f24d94c6..d49a6764a8 100644 --- a/src/Font/Font_FontMgr.cxx +++ b/src/Font/Font_FontMgr.cxx @@ -49,7 +49,8 @@ static const Font_FontMgr_FontAliasMapNode Font_FontMgr_MapOfFontsAliases[] = { "Symbol" , "Symbol" , Font_FA_Regular }, { "ZapfDingbats" , "WingDings" , Font_FA_Regular }, { "Rock" , "Arial" , Font_FA_Regular }, - { "Iris" , "Lucida Console" , Font_FA_Regular } + { "Iris" , "Lucida Console" , Font_FA_Regular }, + { "NSimSun" , "SimSun" , Font_FA_Regular } #elif defined(__ANDROID__) @@ -218,6 +219,8 @@ static Handle(Font_SystemFont) checkFont (const Handle(Font_FTLibrary)& theFTLib Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (aFontFace->family_name); Handle(TCollection_HAsciiString) aFontPath = new TCollection_HAsciiString (theFontPath); aResult = new Font_SystemFont (aFontName, anAspect, aFontPath); + // automatically identify some known single-line fonts + aResult->SetSingleStrokeFont (aFontName->String().StartsWith ("OLF ")); } FT_Done_Face (aFontFace); diff --git a/src/Font/Font_SystemFont.cxx b/src/Font/Font_SystemFont.cxx index 29f1653bd3..19c3c1636d 100644 --- a/src/Font/Font_SystemFont.cxx +++ b/src/Font/Font_SystemFont.cxx @@ -13,126 +13,113 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. -// Updated: - #include + #include #include #include -IMPLEMENT_STANDARD_RTTIEXT(Font_SystemFont,Standard_Transient) - -Font_SystemFont::Font_SystemFont(): -MyFontName(), -MyFontAspect(Font_FA_Undefined), -MyFaceSize(-1), -MyVerification(Standard_False) +IMPLEMENT_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient) + +// ======================================================================= +// function : Font_SystemFont +// purpose : +// ======================================================================= +Font_SystemFont::Font_SystemFont() +: myFontAspect (Font_FA_Undefined), + myFaceSize (-1), + myIsSingleLine (Standard_False), + myIsDefined (Standard_False) { + // } -Font_SystemFont::Font_SystemFont( const Handle(TCollection_HAsciiString)& FontName, - const Font_FontAspect FontAspect, - const Handle(TCollection_HAsciiString)& FilePath ): -MyFontName(FontName), -MyFontAspect(FontAspect), -MyFaceSize(-1), -MyFilePath(FilePath), -MyVerification(Standard_True) +// ======================================================================= +// function : Font_SystemFont +// purpose : +// ======================================================================= +Font_SystemFont::Font_SystemFont (const Handle(TCollection_HAsciiString)& theFontName, + const Font_FontAspect theFontAspect, + const Handle(TCollection_HAsciiString)& theFilePath) +: myFontName (theFontName), + myFontAspect (theFontAspect), + myFaceSize (-1), + myFilePath (theFilePath), + myIsSingleLine (Standard_False), + myIsDefined (Standard_True) { - + // } +// ======================================================================= +// function : Font_SystemFont +// purpose : +// ======================================================================= Font_SystemFont::Font_SystemFont (const Handle(TCollection_HAsciiString)& theXLFD, - const Handle(TCollection_HAsciiString)& theFilePath) : -MyFontAspect(Font_FA_Regular), -MyFaceSize(-1), -MyFilePath(theFilePath) + const Handle(TCollection_HAsciiString)& theFilePath) +: myFontAspect (Font_FA_Regular), + myFaceSize (-1), + myFilePath (theFilePath), + myIsSingleLine (Standard_False), + myIsDefined (Standard_True) { - MyVerification = Standard_True; - if (theXLFD.IsNull()) + if (theXLFD.IsNull() + || theXLFD->IsEmpty()) { - MyVerification = Standard_False; // empty font description handler + myIsDefined = Standard_False; + return; } - if (theXLFD->IsEmpty()) + + myFontName = theXLFD->Token ("-", 2); + const TCollection_AsciiString& aXLFD = theXLFD->String(); + + // Getting font size for fixed size fonts + if (aXLFD.Search ("-0-0-0-0-") >= 0) { - MyVerification = Standard_False; // empty font description + myFaceSize = -1; // Scalable font } - - if (MyVerification) + else { - MyFontName = theXLFD->Token ("-", 2); - TCollection_AsciiString aXLFD (theXLFD->ToCString()); - - // Getting font size for fixed size fonts - if (aXLFD.Search ("-0-0-0-0-") >= 0) - MyFaceSize = -1; // Scalable font - else - //TODO catch exeption - MyFaceSize = aXLFD.Token ("-", 7).IntegerValue(); - - // Detect font aspect - if (aXLFD.Token ("-", 3).IsEqual ("bold") && - (aXLFD.Token ("-", 4).IsEqual ("i") || aXLFD.Token ("-", 4).IsEqual ("o"))) - { - MyFontAspect = Font_FA_BoldItalic; - } - else if (aXLFD.Token ("-", 3).IsEqual ("bold")) - { - MyFontAspect = Font_FA_Bold; - } - else if (aXLFD.Token ("-", 4).IsEqual ("i") || aXLFD.Token ("-", 4).IsEqual ("o")) - { - MyFontAspect = Font_FA_Italic; - } + myFaceSize = aXLFD.Token ("-", 7).IntegerValue(); } -} - -Standard_Boolean Font_SystemFont::IsValid() const{ - if ( !MyVerification) - return Standard_False; - - if ( MyFontAspect == Font_FA_Undefined ) - return Standard_False; - if ( MyFontName->IsEmpty() || !MyFontName->IsAscii() ) - return Standard_False; - - OSD_Path path; - return path.IsValid( MyFilePath->String() ); -} - -Handle(TCollection_HAsciiString) Font_SystemFont::FontPath() const{ - return MyFilePath; -} - -Handle(TCollection_HAsciiString) Font_SystemFont::FontName() const{ - return MyFontName; -} - -Font_FontAspect Font_SystemFont::FontAspect() const{ - return MyFontAspect; -} - -Standard_Integer Font_SystemFont::FontHeight() const { - return MyFaceSize; -} - -Standard_Boolean Font_SystemFont::IsEqual(const Handle(Font_SystemFont)& theOtherFont) const -{ - if (!MyFontName->IsSameString (theOtherFont->FontName(), Standard_False)) + // Detect font aspect + if (aXLFD.Token ("-", 3).IsEqual ("bold") + && (aXLFD.Token ("-", 4).IsEqual ("i") + || aXLFD.Token ("-", 4).IsEqual ("o"))) { - return Standard_False; + myFontAspect = Font_FA_BoldItalic; } - - if (MyFontAspect != theOtherFont->FontAspect()) + else if (aXLFD.Token ("-", 3).IsEqual ("bold")) { - return Standard_False; + myFontAspect = Font_FA_Bold; } - - if (MyFaceSize != theOtherFont->FontHeight()) + else if (aXLFD.Token ("-", 4).IsEqual ("i") + || aXLFD.Token ("-", 4).IsEqual ("o")) { - return Standard_False; + myFontAspect = Font_FA_Italic; } +} - return Standard_True; +// ======================================================================= +// function : IsValid +// purpose : +// ======================================================================= +Standard_Boolean Font_SystemFont::IsValid() const +{ + return myIsDefined + && myFontAspect != Font_FA_Undefined + && !myFontName->IsEmpty() + && OSD_Path::IsValid (myFilePath->String()); +} + +// ======================================================================= +// function : IsEqual +// purpose : +// ======================================================================= +Standard_Boolean Font_SystemFont::IsEqual (const Handle(Font_SystemFont)& theOtherFont) const +{ + return myFontName->IsSameString (myFontName, Standard_False) + && myFontAspect == theOtherFont->myFontAspect + && myFaceSize == theOtherFont->myFaceSize; } diff --git a/src/Font/Font_SystemFont.hxx b/src/Font/Font_SystemFont.hxx index 062f916d51..7cb13e25de 100644 --- a/src/Font/Font_SystemFont.hxx +++ b/src/Font/Font_SystemFont.hxx @@ -25,76 +25,60 @@ #include class TCollection_HAsciiString; - -class Font_SystemFont; -DEFINE_STANDARD_HANDLE(Font_SystemFont, Standard_Transient) - -//! Structure for store of Font System Information +//! This class stores information about the font, which is merely a file path and cached metadata about the font. class Font_SystemFont : public Standard_Transient { - + DEFINE_STANDARD_RTTIEXT(Font_SystemFont, Standard_Transient) public: - - //! Creates empty font object + //! Creates an empty font object. Standard_EXPORT Font_SystemFont(); + + //! Creates a new font object. + Standard_EXPORT Font_SystemFont (const Handle(TCollection_HAsciiString)& theFontName, + const Font_FontAspect theFontAspect, + const Handle(TCollection_HAsciiString)& theFilePath); + + //! Creates a font object and initialize class fields with values taken from XLFD (X Logical Font Description) + Standard_EXPORT Font_SystemFont (const Handle(TCollection_HAsciiString)& theXLFD, + const Handle(TCollection_HAsciiString)& theFilePath); + + //! Returns font family name. + const Handle(TCollection_HAsciiString)& FontName() const { return myFontName; } - //! Creates Font object initialized with as name - //! .... TODO - Standard_EXPORT Font_SystemFont(const Handle(TCollection_HAsciiString)& theFontName, const Font_FontAspect theFontAspect, const Handle(TCollection_HAsciiString)& theFilePath); - - //! Creates Font object and initialize class fields with - //! values taken from XLFD (X Logical Font Description) - Standard_EXPORT Font_SystemFont(const Handle(TCollection_HAsciiString)& theXLFD, const Handle(TCollection_HAsciiString)& theFilePath); - - //! Returns font family name - Standard_EXPORT Handle(TCollection_HAsciiString) FontName() const; - - //! Returns font file path - //! Level: Public - Standard_EXPORT Handle(TCollection_HAsciiString) FontPath() const; - - //! Returns font aspect - //! Level: Public - Standard_EXPORT Font_FontAspect FontAspect() const; + //! Returns font file path. + const Handle(TCollection_HAsciiString)& FontPath() const { return myFilePath; } - //! Returns font height - //! If returned value is equal -1 it means that font is resizable - //! Level: Public - Standard_EXPORT Standard_Integer FontHeight() const; + //! Returns font aspect. + Font_FontAspect FontAspect() const { return myFontAspect; } + //! Returns font height. + //! If returned value is equal -1 it means that font is resizable. + Standard_Integer FontHeight() const { return myFaceSize; } + Standard_EXPORT Standard_Boolean IsValid() const; //! Return true if the FontName, FontAspect and FontSize are the same. - //! Level: Public Standard_EXPORT Standard_Boolean IsEqual (const Handle(Font_SystemFont)& theOtherFont) const; + //! Return TRUE if this is single-stroke (one-line) font, FALSE by default. + //! Such fonts define single-line glyphs instead of closed contours, so that they are rendered incorrectly by normal software. + Standard_Boolean IsSingleStrokeFont() const { return myIsSingleLine; } - - - DEFINE_STANDARD_RTTIEXT(Font_SystemFont,Standard_Transient) - -protected: - - - + //! Set if this font should be rendered as single-stroke (one-line). + void SetSingleStrokeFont (Standard_Boolean theIsSingleLine) { myIsSingleLine = theIsSingleLine; } private: - - Handle(TCollection_HAsciiString) MyFontName; - Font_FontAspect MyFontAspect; - Standard_Integer MyFaceSize; - Handle(TCollection_HAsciiString) MyFilePath; - Standard_Boolean MyVerification; - + Handle(TCollection_HAsciiString) myFontName; + Font_FontAspect myFontAspect; + Standard_Integer myFaceSize; + Handle(TCollection_HAsciiString) myFilePath; + Standard_Boolean myIsSingleLine; //!< single stroke font flag, FALSE by default + Standard_Boolean myIsDefined; }; - - - - - +DEFINE_STANDARD_HANDLE(Font_SystemFont, Standard_Transient) #endif // _Font_SystemFont_HeaderFile diff --git a/src/Geom/Geom_ConicalSurface.cxx b/src/Geom/Geom_ConicalSurface.cxx index 5dd0e7029b..948258483e 100644 --- a/src/Geom/Geom_ConicalSurface.cxx +++ b/src/Geom/Geom_ConicalSurface.cxx @@ -229,13 +229,21 @@ void Geom_ConicalSurface::SetSemiAngle (const Standard_Real Ang) { //function : Apex //purpose : //======================================================================= - Pnt Geom_ConicalSurface::Apex () const +{ + return Apex(0L); +} + +Pnt Geom_ConicalSurface::Apex(Standard_Real* const theVParametr) const { XYZ Coord = Position().Direction().XYZ(); Coord.Multiply (-radius / Tan (semiAngle)); Coord.Add (Position().Location().XYZ()); + + if (theVParametr) + *theVParametr = -radius / Sin(semiAngle); + return Pnt (Coord); } diff --git a/src/Geom/Geom_ConicalSurface.hxx b/src/Geom/Geom_ConicalSurface.hxx index 40ac5b531a..da7c0513fa 100644 --- a/src/Geom/Geom_ConicalSurface.hxx +++ b/src/Geom/Geom_ConicalSurface.hxx @@ -179,7 +179,10 @@ public: //! side of the axis of revolution of this cone if the //! half-angle at the apex is positive, and on the positive //! side of the "main Axis" if the half-angle is negative. + //! If theVParametr != 0 (points on the real variable) then it will store + //! the V-parameter of the apex. Standard_EXPORT gp_Pnt Apex() const; + Standard_EXPORT gp_Pnt Apex(Standard_Real* const theVParametr) const; //! The conical surface is infinite in the V direction so diff --git a/src/GeomLib/GeomLib.cxx b/src/GeomLib/GeomLib.cxx index 5d7b6a2489..b45f7575d8 100644 --- a/src/GeomLib/GeomLib.cxx +++ b/src/GeomLib/GeomLib.cxx @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -74,16 +75,19 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -962,14 +966,7 @@ void GeomLib::SameRange(const Standard_Real Tolerance, else { // On segmente le resultat Handle(Geom2d_TrimmedCurve) TC; - Handle(Geom2d_Curve) aCCheck = CurvePtr; - - if(aCCheck->IsKind(STANDARD_TYPE(Geom2d_TrimmedCurve))) - { - aCCheck = Handle(Geom2d_TrimmedCurve)::DownCast(aCCheck)->BasisCurve(); - } - - if(aCCheck->IsPeriodic()) + if (CurvePtr->IsPeriodic()) { TC = new Geom2d_TrimmedCurve( CurvePtr, FirstOnCurve, LastOnCurve ); } @@ -2737,12 +2734,148 @@ Standard_Boolean GeomLib::IsBzVClosed (const Handle(Geom_BezierSurface)& S, return CompareWeightPoles(aPF, 0, aPL, 0, Tol2); } +//======================================================================= +//function : AllowExtendUParameter +//purpose : +//======================================================================= +Standard_Boolean GeomLib::IsUTrimAllowed(const GeomAdaptor_Surface& theS, + const Standard_Real theNewUFirst, + const Standard_Real theNewULast) +{ + const Handle(Geom_Surface) &aSurf = theS.Surface(); + + Standard_Real anIsoParameter = theS.FirstVParameter(); + if (Precision::IsInfinite(anIsoParameter)) + anIsoParameter = theS.LastVParameter(); + + if (Precision::IsInfinite(anIsoParameter)) + anIsoParameter = 0.0; + + Handle(Geom_Curve) aC = aSurf->VIso(anIsoParameter); + + if (aC->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) + { + // In order to obtain the default curve's work range + aC = Handle(Geom_TrimmedCurve)::DownCast(aC)->BasisCurve(); + } + + return (IsTrimAllowed(aC, theNewUFirst, theNewULast)); +} + +//======================================================================= +//function : AllowExtendVParameter +//purpose : +//======================================================================= +Standard_Boolean GeomLib::IsVTrimAllowed(const GeomAdaptor_Surface& theS, + const Standard_Real theNewVFirst, + const Standard_Real theNewVLast) +{ + const GeomAbs_SurfaceType aSType = theS.GetType(); + + const Handle(Geom_Surface) &aSurf = theS.Surface(); + + if (aSType == GeomAbs_OffsetSurface) + { + const Handle(Geom_OffsetSurface) aOS = Handle(Geom_OffsetSurface)::DownCast(aSurf); + return IsVTrimAllowed(GeomAdaptor_Surface(aOS->BasisSurface()), + theNewVFirst, theNewVLast); + } + + Standard_Real anIsoParameter = theS.FirstUParameter(); + if (Precision::IsInfinite(anIsoParameter)) + anIsoParameter = theS.LastUParameter(); + + if (Precision::IsInfinite(anIsoParameter)) + anIsoParameter = 0.0; + + Handle(Geom_Curve) aC = aSurf->UIso(anIsoParameter); + + if (aC.IsNull()) + return Standard_False; + + if (aC->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) + { + // In order to obtain the default curve's work range + aC = Handle(Geom_TrimmedCurve)::DownCast(aC)->BasisCurve(); + } + + if (!IsTrimAllowed(aC, theNewVFirst, theNewVLast)) + return Standard_False; + + switch (aSType) + { + case GeomAbs_OtherSurface: + return Standard_True; + case GeomAbs_Sphere: + { + if ((theNewVFirst < -M_PI_2) || (theNewVLast > M_PI_2)) + { + // After extending, the surface isoline will go + // through the sphere pole + return Standard_False; + } + } + break; + case GeomAbs_Cone: + { + const Handle(Geom_ConicalSurface) aCone = Handle(Geom_ConicalSurface)::DownCast(aSurf); + Standard_Real anApexPrm = 0.0; + aCone->Apex(&anApexPrm); + + if ((anApexPrm - theNewVFirst)*(theNewVLast - anApexPrm) > 0.0) + { + // The new boundaries intersect the cone apex + return Standard_False; + } + } + break; + case GeomAbs_SurfaceOfRevolution: + { + const Handle(Adaptor3d_HCurve) aCurv = theS.BasisCurve(); + + const Standard_Real aParTol = aCurv->Resolution(Precision::Confusion()); + + const Standard_Real aParF = theNewVFirst + aParTol, + aParL = theNewVLast - aParTol; + + const Handle(Geom_Line) aL = new Geom_Line(theS.AxeOfRevolution()); + const GeomAdaptor_Curve aLin(aL); + + Extrema_ECC anExtr(aCurv->Curve(), aLin); + anExtr.Perform(); + if (anExtr.IsDone() && anExtr.NbExt() > 0) + { + Extrema_POnCurv aP1, aP2; + for (Standard_Integer i = 1; i <= anExtr.NbExt(); i++) + { + if (anExtr.SquareDistance(i) > Precision::SquareConfusion()) + continue; + + anExtr.Points(i, aP1, aP2); + if ((aParF < aP1.Parameter()) && (aP1.Parameter() < aParL)) + { + // After extending, the surface isoline will go + // through the pole (singular point like pole of sphere) + + return Standard_False; + } + } + } + } + break; + default: + break; + } + + return Standard_True; +} + //======================================================================= //function : CompareWeightPoles //purpose : Checks if thePoles1(i)*theW1(i) is equal to thePoles2(i)*theW2(i) // with tolerance theTol. // It is necessary for not rational B-splines and Bezier curves -// to set theW1 and theW2 adresses to zero. +// to set theW1 and theW2 addresses to zero. //======================================================================= static Standard_Boolean CompareWeightPoles(const TColgp_Array1OfPnt& thePoles1, const TColStd_Array1OfReal* const theW1, diff --git a/src/GeomLib/GeomLib.hxx b/src/GeomLib/GeomLib.hxx index b51028d2fc..f08af33cec 100644 --- a/src/GeomLib/GeomLib.hxx +++ b/src/GeomLib/GeomLib.hxx @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,7 @@ class gp_Ax2; class Geom2d_Curve; class gp_GTrsf2d; class Adaptor3d_CurveOnSurface; +class GeomAdaptor_Surface; class Geom_BoundedCurve; class gp_Pnt; class gp_Vec; @@ -54,7 +56,6 @@ class GeomLib_Tool; class GeomLib_PolyFunc; class GeomLib_LogSample; - //! Geom Library. This package provides an //! implementation of functions for basic computation //! on geometric entity from packages Geom and Geom2d. @@ -193,6 +194,71 @@ public: Standard_EXPORT static void IsClosed(const Handle(Geom_Surface)& S, const Standard_Real Tol, Standard_Boolean& isUClosed, Standard_Boolean& isVClosed); + //! This method determines if the ends of the given curve are + //! coincided with given tolerance. + //! This is a template-method. Therefore, it can be applied to + //! 2D- and 3D-curve and to Adaptor-HCurve. + template + Standard_EXPORT static Standard_Boolean IsClosed(const Handle(TypeCurve)& theCurve, + const Standard_Real theTol) + { + const Standard_Real aFPar = theCurve->FirstParameter(), + aLPar = theCurve->LastParameter(); + + if (Precision::IsInfinite(aFPar) || Precision::IsInfinite(aLPar)) + return Standard_False; + + return (theCurve->Value(aFPar).SquareDistance(theCurve->Value(aLPar)) < theTol*theTol); + } + + //! Returns TRUE if theCurve will keep its validity for OCCT-algorithms + //! after its trimming in range [theNewFPar, theNewLPar]. + //! This is a template-method. Therefore, it can be applied to + //! 2D- and 3D-curve. + //! Using trimmed curves or Adaptor_HCurves is possible but undesirable + //! because theCurve must be parametrized in its default work-range + //! in order for this method to work correctly. + template + Standard_EXPORT static Standard_Boolean IsTrimAllowed(const Handle(TypeCurve)& theCurve, + const Standard_Real theNewFPar, + const Standard_Real theNewLPar) + { + Standard_Real aFPar = theCurve->FirstParameter(), + aLPar = theCurve->LastParameter(); + + if ((aFPar <= theNewFPar) && (theNewLPar <= aLPar) && (theNewFPar < theNewLPar)) + { + //New boundaries are in the current ones + return Standard_True; + } + + if (!theCurve->IsPeriodic()) + { + return Standard_False; + } + + const Standard_Real aPeriod = theCurve->Period(); + + if ((theNewLPar - theNewFPar - aPeriod) > Epsilon(aPeriod)) + return Standard_False; + + return Standard_True; + } + + //! Returns TRUE if theS will keep its validity for OCCT-algorithms + //! after its trimming in range [theNewUFirst, theNewULast] along U-direction + Standard_EXPORT static Standard_Boolean + IsUTrimAllowed(const GeomAdaptor_Surface& theS, + const Standard_Real theNewUFirst, + const Standard_Real theNewULast); + + //! Returns TRUE if theS will keep its validity for OCCT-algorithms + //! after its trimming in range [theNewVFirst, theNewVLast] along V-direction + Standard_EXPORT static Standard_Boolean + IsVTrimAllowed(const GeomAdaptor_Surface& theS, + const Standard_Real theNewVFirst, + const Standard_Real theNewVLast); + //! Returns true if the poles of U1 isoline and the poles of //! U2 isoline of surface are identical according to tolerance criterion. //! For rational surfaces Weights(i)*Poles(i) are checked. diff --git a/src/Image/Image_VideoRecorder.cxx b/src/Image/Image_VideoRecorder.cxx index 9af4c31583..12d97aa70f 100644 --- a/src/Image/Image_VideoRecorder.cxx +++ b/src/Image/Image_VideoRecorder.cxx @@ -41,10 +41,12 @@ extern "C" #pragma warning(disable : 4244) #endif +#ifdef HAVE_FFMPEG #include #include #include #include +#endif #ifdef _MSC_VER #pragma warning(default : 4244) diff --git a/src/IntWalk/IntWalk_PWalking.cxx b/src/IntWalk/IntWalk_PWalking.cxx index 54c42a1304..a554c13e80 100644 --- a/src/IntWalk/IntWalk_PWalking.cxx +++ b/src/IntWalk/IntWalk_PWalking.cxx @@ -687,7 +687,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, } // Standard_Boolean Arrive, DejaReparti; - const Standard_Integer RejectIndexMAX = 250000; + const Standard_Integer RejectIndexMAX = 25000; Standard_Integer IncKey, RejectIndex; gp_Pnt pf,pl; // @@ -736,6 +736,12 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, Arrive = Standard_False; while(!Arrive) //010 { + if (line->NbPoints() >= RejectIndexMAX) + { + Arrive = Standard_True; + break; + } + aPrevStatus = aStatus; LevelOfIterWithoutAppend++; @@ -745,7 +751,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, if(DejaReparti) { break; } - RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); + RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive); LevelOfIterWithoutAppend = 0; } // @@ -872,7 +878,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, Param(2)=SvParam[1]; Param(3)=SvParam[2]; Param(4)=SvParam[3]; - RepartirOuDiviser(DejaReparti, ChoixIso, Arrive); + RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive); } else //009 { @@ -903,7 +909,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, Arrive=Standard_True; } - RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); + RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive); LevelOfEmptyInmyIntersectionOn2S++; // if(LevelOfEmptyInmyIntersectionOn2S>10) @@ -1036,7 +1042,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, case IntWalk_ArretSurPointPrecedent: { Arrive = Standard_False; - RepartirOuDiviser(DejaReparti, ChoixIso, Arrive); + RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive); break; } case IntWalk_PasTropGrand: @@ -1046,7 +1052,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, Param(3)=SvParam[2]; Param(4)=SvParam[3]; - if(LevelOfIterWithoutAppend > 5) + if ((LevelOfIterWithoutAppend > 5) && (aPrevStatus != IntWalk_StepTooSmall)) { for (Standard_Integer i = 0; i < 4; i++) { @@ -1240,7 +1246,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, if (aStatus == IntWalk_ArretSurPoint) { - RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); + RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive); } else { @@ -1321,13 +1327,13 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, // LevelOfIterWithoutAppend=0; - RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); + RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive); } else { //fail framing divides the step Arrive = Standard_False; - RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); + RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive); NoTestDeflection = Standard_True; ChoixIso = SauvChoixIso; } @@ -1582,7 +1588,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, } } - RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); + RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive); if(Arrive && myIntersectionOn2S.IsDone() && !myIntersectionOn2S.IsEmpty() && @@ -1603,7 +1609,7 @@ void IntWalk_PWalking::Perform(const TColStd_Array1OfReal& ParDep, //echec framing on border; division of step Arrive = Standard_False; NoTestDeflection = Standard_True; - RepartirOuDiviser(DejaReparti,ChoixIso,Arrive); + RepartirOuDiviser(aStatus, DejaReparti, ChoixIso, Arrive); } }//$$$ end framing on border (!close) }//004 fin TestArret return Arrive = True @@ -2769,16 +2775,17 @@ SeekAdditionalPoints( const Handle(Adaptor3d_HSurface)& theASurf1, return isPrecise; } -void IntWalk_PWalking:: -RepartirOuDiviser(Standard_Boolean& DejaReparti, - IntImp_ConstIsoparametric& ChoixIso, - Standard_Boolean& Arrive) - - // at the neighborhood of a point, there is a fail of marching - // it is required to divide the steps to try to continue - // if the step is too small if we are on border - // restart in another direction if it was not done, otherwise stop - +//======================================================================= +//function : RepartirOuDiviser +//purpose : at the neighborhood of a point, there is a fail of marching +// it is required to divide the steps to try to continue +// if the step is too small if we are on border +// restart in another direction if it was not done, otherwise stop +//======================================================================= +void IntWalk_PWalking::RepartirOuDiviser(const IntWalk_StatusDeflection& theCurrentStatus, + Standard_Boolean& DejaReparti, + IntImp_ConstIsoparametric& ChoixIso, + Standard_Boolean& Arrive) { // Standard_Integer i; if (Arrive) { //restart in the other direction @@ -2821,11 +2828,12 @@ RepartirOuDiviser(Standard_Boolean& DejaReparti, } } else { - if ( pasuv[0]*0.5 < ResoU1 - && pasuv[1]*0.5 < ResoV1 - && pasuv[2]*0.5 < ResoU2 - && pasuv[3]*0.5 < ResoV2 - ) { + if ((theCurrentStatus == IntWalk_StepTooSmall) || + (pasuv[0] * 0.5 < ResoU1 + && pasuv[1] * 0.5 < ResoV1 + && pasuv[2] * 0.5 < ResoU2 + && pasuv[3] * 0.5 < ResoV2)) + { if (!previoustg) { tglast = Standard_True; // IS IT ENOUGH ???? } diff --git a/src/IntWalk/IntWalk_PWalking.hxx b/src/IntWalk/IntWalk_PWalking.hxx index e4dab8ed9a..b2efdb1cea 100644 --- a/src/IntWalk/IntWalk_PWalking.hxx +++ b/src/IntWalk/IntWalk_PWalking.hxx @@ -130,7 +130,10 @@ public: Standard_EXPORT Standard_Boolean TestArret (const Standard_Boolean DejaReparti, TColStd_Array1OfReal& Param, IntImp_ConstIsoparametric& ChoixIso); - Standard_EXPORT void RepartirOuDiviser (Standard_Boolean& DejaReparti, IntImp_ConstIsoparametric& ChoixIso, Standard_Boolean& Arrive); + Standard_EXPORT void RepartirOuDiviser(const IntWalk_StatusDeflection& theCurrentStatus, + Standard_Boolean& DejaReparti, + IntImp_ConstIsoparametric& ChoixIso, + Standard_Boolean& Arrive); void AddAPoint (Handle(IntSurf_LineOn2S)& line, const IntSurf_PntOn2S& POn2S); diff --git a/src/LocOpe/LocOpe_DPrism.cxx b/src/LocOpe/LocOpe_DPrism.cxx index 8da855d765..362a0269f9 100644 --- a/src/LocOpe/LocOpe_DPrism.cxx +++ b/src/LocOpe/LocOpe_DPrism.cxx @@ -117,7 +117,7 @@ LocOpe_DPrism::LocOpe_DPrism(const TopoDS_Face& Spine, myProfile = BRepLib_MakeWire(myProfile1,myProfile2,myProfile3); - myDPrism.Perform(mySpine,myProfile,gp::XOY()); + myDPrism.Perform(mySpine,myProfile,gp::XOY(), GeomAbs_Arc, Standard_False); if (myDPrism.IsDone()) { @@ -370,7 +370,7 @@ LocOpe_DPrism::LocOpe_DPrism(const TopoDS_Face& Spine, myProfile1 = BRepLib_MakeEdge(Vert4, Vert1); myProfile = BRepLib_MakeWire(myProfile1,myProfile2,myProfile3); - myDPrism.Perform(mySpine,myProfile,gp::XOY()); + myDPrism.Perform(mySpine,myProfile,gp::XOY(), GeomAbs_Arc, Standard_False); if (myDPrism.IsDone()) { diff --git a/src/OpenGl/OpenGl_AVIWriter.cxx b/src/OpenGl/OpenGl_AVIWriter.cxx new file mode 100644 index 0000000000..0bb92cad9a --- /dev/null +++ b/src/OpenGl/OpenGl_AVIWriter.cxx @@ -0,0 +1,471 @@ +// Created on: 2007-04-15 +// Created by: Alexey MORENOV & Alexander GRIGORIEV +// Copyright (c) 2007-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include + +#if (defined(_WIN32) || defined(__WIN32__)) && defined(HAVE_VIDEOCAPTURE) + #ifdef _MSC_VER + #pragma comment (lib, "vfw32.lib") + #endif + +OpenGl_AVIWriter* OpenGl_AVIWriter::MyAVIWriterInstance = 0L; + +OpenGl_AVIWriter * OpenGl_AVIWriter::GetInstance() +{ + return MyAVIWriterInstance; +} + +//======================================================================= +//function : OpenGl_AVIWriter +//purpose : +//======================================================================= + +Standard_EXPORT OpenGl_AVIWriter::OpenGl_AVIWriter + (const wchar_t * theFileName, + DWORD dwCodec /* = mmioFOURCC('M','P','G','4') */, + Standard_Integer theFrameRate /* = 25 */) + : myhHeap (0L), + myhWindow (0L), + myhAviDC (0L), + mylpBits (0L), + mylSample (0L), + mypAviFile (0L), + mypAviStream (0L), + mypAviCompressedStream(0L), + myFileName (0L), + myIsAllowRecord (Standard_False), + myAppendFuncSelector(1) //0=Dummy 1=FirstTime 2=Usual +{ + ::AVIFileInit(); + if (theFileName != 0L && theFileName[0] != L'\0') { + + const size_t aLen = wcslen(theFileName) + 1; + myFileName = new wchar_t [aLen]; + memcpy(myFileName, theFileName, aLen * sizeof(wchar_t)); + myErrMsg = "Method Succeeded"; + + pAppendFrame[0]= &OpenGl_AVIWriter::AppendDummy; + pAppendFrame[1]= &OpenGl_AVIWriter::AppendFrameFirstTime; + pAppendFrame[2]= &OpenGl_AVIWriter::AppendFrameUsual; + + pAppendFrameBits[0]=&OpenGl_AVIWriter::AppendDummyBits; + pAppendFrameBits[1]=&OpenGl_AVIWriter::AppendFrameBitsFirstTime; + pAppendFrameBits[2]=&OpenGl_AVIWriter::AppendFrameBitsUsual; + + MyAVIWriterInstance = this; + + ZeroMemory(&myAviStreamInfo,sizeof(AVISTREAMINFOW)); + myAviStreamInfo.fccType = streamtypeVIDEO; + myAviStreamInfo.fccHandler = dwCodec; + myAviStreamInfo.dwScale = 1; + myAviStreamInfo.dwRate = theFrameRate; // Frames Per Second; + myAviStreamInfo.dwQuality = 100;/*//-1; // Default Quality*/ + + ZeroMemory(&myAviCompressOptions,sizeof(AVICOMPRESSOPTIONS)); + myAviCompressOptions.fccType = streamtypeVIDEO; + myAviCompressOptions.fccHandler = myAviStreamInfo.fccHandler; + myAviCompressOptions.dwFlags = + AVICOMPRESSF_KEYFRAMES|AVICOMPRESSF_VALID|AVICOMPRESSF_DATARATE; + myAviCompressOptions.dwKeyFrameEvery = 1; + myAviCompressOptions.dwBytesPerSecond = 125000; + myAviCompressOptions.dwQuality = 100; + } +} + +//======================================================================= +//function : ~OpenGl_AVIWriter +//purpose : +//======================================================================= + +Standard_EXPORT OpenGl_AVIWriter::~OpenGl_AVIWriter(void) +{ + ReleaseMemory(); + AVIFileExit(); + if (myFileName) + delete [] myFileName; + MyAVIWriterInstance = 0L; +} + +//======================================================================= +//function : StartRecording +//purpose : +//======================================================================= + +void OpenGl_AVIWriter::StartRecording(const HANDLE hWin) +{ + if (hWin != NULL) + myhWindow = hWin; + myIsAllowRecord = Standard_True; +} + +//======================================================================= +//function : StopRecording +//purpose : +//======================================================================= + +void OpenGl_AVIWriter::StopRecording() +{ + myIsAllowRecord = Standard_False; +} + +//======================================================================= +//function : ReleaseMemory +//purpose : +//======================================================================= + +void OpenGl_AVIWriter::ReleaseMemory() +{ + myAppendFuncSelector=0; //Point to DummyFunction + + if (myhAviDC) + { + DeleteDC(myhAviDC); + myhAviDC=NULL; + } + if (mypAviCompressedStream) + { + AVIStreamRelease(mypAviCompressedStream); + mypAviCompressedStream=NULL; + } + if (mypAviStream) + { + AVIStreamRelease(mypAviStream); + mypAviStream=NULL; + } + if (mypAviFile) + { + AVIFileRelease(mypAviFile); + mypAviFile=NULL; + } + if (mylpBits) + { + HeapFree(myhHeap,HEAP_NO_SERIALIZE,mylpBits); + mylpBits=NULL; + } + if (myhHeap) + { + HeapDestroy(myhHeap); + myhHeap=NULL; + } +} + +//======================================================================= +//function : SetErrorMessage +//purpose : +//======================================================================= + +void OpenGl_AVIWriter::SetErrorMessage(const char * theErrorMessage) +{ + myErrMsg = theErrorMessage; +} + +//======================================================================= +//function : InitMovieCreation +//purpose : +//======================================================================= + +HRESULT OpenGl_AVIWriter::InitMovieCreation (int nFrameWidth, + int nFrameHeight, + int nBitsPerPixel) +{ + int nMaxWidth=GetSystemMetrics(SM_CXSCREEN), + nMaxHeight=GetSystemMetrics(SM_CYSCREEN); + + myhAviDC = CreateCompatibleDC(NULL); + if (myhAviDC == NULL) + { + SetErrorMessage("Unable to Create Compatible DC"); + return E_FAIL; + } + + if (nFrameWidth > nMaxWidth) + nMaxWidth= nFrameWidth; + if (nFrameHeight > nMaxHeight) + nMaxHeight = nFrameHeight; + + myhHeap = HeapCreate(HEAP_NO_SERIALIZE, nMaxWidth*nMaxHeight*4, 0); + if (myhHeap == NULL) + { + SetErrorMessage("Unable to Create Heap"); + return E_FAIL; + } + + mylpBits = HeapAlloc(myhHeap, HEAP_ZERO_MEMORY|HEAP_NO_SERIALIZE, + nMaxWidth*nMaxHeight*4); + if (mylpBits == NULL) + { + SetErrorMessage("Unable to Allocate Memory on Heap"); + return E_FAIL; + } + + HRESULT hr; + hr = ::AVIFileOpenW(&mypAviFile, myFileName, OF_CREATE|OF_WRITE, NULL); + if (!hr == AVIERR_OK) + { + SetErrorMessage("Unable to Create the Movie File"); + return E_FAIL; + } + + myAviStreamInfo.dwSuggestedBufferSize = nMaxWidth * nMaxHeight * 4; + SetRect(&myAviStreamInfo.rcFrame, 0, 0, nFrameWidth, nFrameHeight); + wcsncpy(myAviStreamInfo.szName, L"Video Stream", 64); + + if (FAILED(AVIFileCreateStreamW(mypAviFile, &mypAviStream, &myAviStreamInfo))) + { + SetErrorMessage("Unable to Create Video Stream in the Movie File"); + return E_FAIL; + } + + if (FAILED(AVIMakeCompressedStream(&mypAviCompressedStream, + mypAviStream, + &myAviCompressOptions, + NULL))) + { + // One reason this error might occur is if you are using a Codec that is not + // available on your system. Check the mmioFOURCC() code you are using and + // make sure you have that codec installed properly on your machine. + SetErrorMessage("Unable to Create Compressed Stream: " + "Check your CODEC options"); + return E_FAIL; + } + + BITMAPINFO bmpInfo; + ZeroMemory(&bmpInfo,sizeof(BITMAPINFO)); + bmpInfo.bmiHeader.biPlanes = 1; + bmpInfo.bmiHeader.biWidth = nFrameWidth; + bmpInfo.bmiHeader.biHeight = nFrameHeight; + bmpInfo.bmiHeader.biCompression = BI_RGB; + bmpInfo.bmiHeader.biBitCount = static_cast(nBitsPerPixel); + bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmpInfo.bmiHeader.biSizeImage = (bmpInfo.bmiHeader.biWidth * + bmpInfo.bmiHeader.biHeight* + bmpInfo.bmiHeader.biBitCount)/8; + + if (FAILED(AVIStreamSetFormat(mypAviCompressedStream, + 0, + (LPVOID)&bmpInfo, + bmpInfo.bmiHeader.biSize))) + { + // One reason this error might occur is if your bitmap does not meet + // the Codec requirements. + // For example, + // your bitmap is 32bpp while the Codec supports only 16 or 24 bpp; Or + // your bitmap is 274 * 258 size, while the Codec supports only sizes + // that are powers of 2; etc... + // Possible solution to avoid this is: make your bitmap suit the codec + // requirements, or Choose a codec that is suitable for your bitmap. + SetErrorMessage("Unable to Set Video Stream Format"); + return E_FAIL; + } + + return S_OK; // Everything went Fine +} + +//======================================================================= +//function : AppendFrameFirstTime +//purpose : +//======================================================================= + +HRESULT OpenGl_AVIWriter::AppendFrameFirstTime(HBITMAP hBitmap) +{ + BITMAP Bitmap; + GetObject(hBitmap, sizeof(BITMAP), &Bitmap); + + if (SUCCEEDED(InitMovieCreation(Bitmap.bmWidth, + Bitmap.bmHeight, + Bitmap.bmBitsPixel))) + { + myAppendFuncSelector = 2; //Point to the UsualAppend Function + return AppendFrameUsual(hBitmap); + } + + ReleaseMemory(); + return E_FAIL; +} + +//======================================================================= +//function : AppendFrameUsual +//purpose : +//======================================================================= + +HRESULT OpenGl_AVIWriter::AppendFrameUsual(HBITMAP hBitmap) +{ + BITMAPINFO bmpInfo; + + bmpInfo.bmiHeader.biBitCount=0; + bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); + + GetDIBits(myhAviDC,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); + + bmpInfo.bmiHeader.biCompression=BI_RGB; + + GetDIBits(myhAviDC, + hBitmap, + 0, + bmpInfo.bmiHeader.biHeight, + mylpBits, + &bmpInfo, + DIB_RGB_COLORS); + + if (FAILED(AVIStreamWrite(mypAviCompressedStream, + mylSample++, + 1, + mylpBits, + bmpInfo.bmiHeader.biSizeImage, + 0, + NULL, + NULL))) + { + SetErrorMessage("Unable to Write Video Stream to the output Movie File"); + ReleaseMemory(); + return E_FAIL; + } + + return S_OK; +} + +//======================================================================= +//function : AppendDummy +//purpose : +//======================================================================= + +HRESULT OpenGl_AVIWriter::AppendDummy(HBITMAP) +{ + return E_FAIL; +} + +//======================================================================= +//function : AppendNewFrame +//purpose : +//======================================================================= + +HRESULT OpenGl_AVIWriter::AppendNewFrame(HBITMAP hBitmap) +{ + return (this->*pAppendFrame[myAppendFuncSelector])((HBITMAP)hBitmap); +} + +//======================================================================= +//function : AppendNewFrame +//purpose : +//======================================================================= + +HRESULT OpenGl_AVIWriter::AppendNewFrame(int nWidth, + int nHeight, + LPVOID pBits, + int nBitsPerPixel) +{ + return (this->*pAppendFrameBits[myAppendFuncSelector])(nWidth, + nHeight, + pBits, + nBitsPerPixel); +} + +//======================================================================= +//function : AppendFrameFirstTime +//purpose : +//======================================================================= + +HRESULT OpenGl_AVIWriter::AppendFrameBitsFirstTime(int nWidth, + int nHeight, + LPVOID pBits, + int nBitsPerPixel) +{ + if (SUCCEEDED(InitMovieCreation(nWidth, nHeight, nBitsPerPixel))) + { + myAppendFuncSelector=2; //Point to the UsualAppend Function + return AppendFrameBitsUsual(nWidth, nHeight, pBits, nBitsPerPixel); + } + ReleaseMemory(); + + return E_FAIL; +} + +//======================================================================= +//function : AppendFrameUsual +//purpose : +//======================================================================= + +HRESULT OpenGl_AVIWriter::AppendFrameBitsUsual(int nWidth, + int nHeight, + LPVOID pBits, + int nBitsPerPixel) +{ + DWORD dwSize=nWidth*nHeight*nBitsPerPixel/8; + + if (FAILED(AVIStreamWrite(mypAviCompressedStream, + mylSample++, + 1, + pBits, + dwSize, + 0, + NULL, + NULL))) + { + SetErrorMessage("Unable to Write Video Stream to the output Movie File"); + ReleaseMemory(); + return E_FAIL; + } + + return S_OK; +} + +//======================================================================= +//function : AppendDummy +//purpose : +//======================================================================= + +HRESULT OpenGl_AVIWriter::AppendDummyBits(int /*nWidth*/, + int /*nHeight*/, + LPVOID /*pBits*/, + int /*nBitsPerPixel*/) +{ + return E_FAIL; +} + +//======================================================================= +//function : AviWriter +//purpose : +//======================================================================= + +void OpenGl_AVIWriter_AVIWriter(void * pp, + int nWidth, + int nHeight, + int nBitsPerPixel) +{ + OpenGl_AVIWriter * anInst = OpenGl_AVIWriter::GetInstance(); + if (anInst != 0L) + if (anInst->IsRecording()) + { + anInst->AppendNewFrame(nWidth, nHeight, pp, nBitsPerPixel); + } +} + +//======================================================================= +//function : AllowWriting +//purpose : +//======================================================================= + +Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin) +{ + Standard_Boolean aResult(Standard_False); + const OpenGl_AVIWriter * anInst = OpenGl_AVIWriter::GetInstance(); + if (anInst != 0L) { + if (hWin == NULL || anInst->HWindow() == hWin) + aResult = static_cast (anInst->IsRecording()); + } + return aResult; +} + +#endif diff --git a/src/OpenGl/OpenGl_AVIWriter.hxx b/src/OpenGl/OpenGl_AVIWriter.hxx new file mode 100644 index 0000000000..842b5b2bef --- /dev/null +++ b/src/OpenGl/OpenGl_AVIWriter.hxx @@ -0,0 +1,191 @@ +// Created on: 2007-04-15 +// Created by: Alexey MORENOV & Alexander GRIGORIEV +// Copyright (c) 2007-2014 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#ifndef __OPENGL_AVIWRITER_H +#define __OPENGL_AVIWRITER_H + +#if defined(_WIN32) + #include +#endif + +#include + +#if defined(_MSC_VER) && !defined(OCCT_UWP) + +#include +#include +#include + +/** + * Class providing the API to record AVI files using a codec installed in the + * system -- Only on Windows NT/2k/XP/Vista platform under MS Visual Studio. + * The following tasks are supported: + *
    + * + *
  1. Creation of AVI data stream: launched by the constructor. + * The constructor accepts the filename, FOURCC video code and the frame rate + * setting as parameters. + * The default codec name used here is MPG4. To use a different codec, pass + * its FOURCC value as the input parameter for dwCodec. + * For example, + *
      + *
    • pass mmioFOURCC('D','I','V','X') to use DIVX codec, or
    • + *
    • pass mmioFOURCC('I','V','5','0') to use IV50 codec etc...
    • + *
    + * Also, you can pass just 0 to avoid the codecs altogether. In that case, + * the frames would be saved as they are without any compression; However, + * the output movie file size would be very huge in that case. + * + * Finally, make sure you have the codec installed on the machine before + * passing its Fourcc here. + *
  2. + *
  3. + * Start the recording: call the method StartRecording(). This method should be + * called at least once; execution of the constructor does not begin the + * process. + *
  4. + *
  5. + * Stop the recording: call the method StopRecording(). Can be omitted if the + * next to execute would be the destructor. + *
  6. + *
  7. + * Close the AVI file and exit the process of recording. This is done + * automatically by the destructor. + *
  8. + *
+ */ +class OpenGl_AVIWriter +{ +public: + + /** + * Constructor. Initializes the internal data structures, prepares for the + * creation of an AVI stream when the first frame is ready to be captured. + * @param theFileName + * Name of the output movie file to create. + * @param theCodec + * FourCC of the Video Codec to be used for compression + * @param theFrameRate + * The Frames Per Second (FPS) setting to be used for the movie + */ + Standard_EXPORT OpenGl_AVIWriter(const wchar_t * theFileName, + DWORD theCodec = mmioFOURCC('M','P','G','4'), + Standard_Integer theFrameRate = 25); + + /** + * Destructor: closes the movie file and flushes all the frames + */ + Standard_EXPORT ~OpenGl_AVIWriter (); + + /** + * Begin the recording. + */ + Standard_EXPORT void StartRecording(const HANDLE hWin = NULL); + + /** + * Stop the recording (can be restarted using StartRecording()). + */ + Standard_EXPORT void StopRecording (); + + /** + * Query the state of recording. + */ + Standard_Boolean IsRecording () const { return myIsAllowRecord; } + + /** + * Returns the last error message, if any. + */ + const TCollection_AsciiString& GetLastErrorMessage() const + { return myErrMsg; } + + /** + * Get the instance of AVI Writer class. + */ + static Standard_EXPORT OpenGl_AVIWriter * GetInstance (); + + /** + * Get the Window handle that contains the actual OpenGl context. + */ + HANDLE HWindow () const + { return myhWindow; } + + /// Inserts the given HBitmap into the movie as a new Frame at the end. + HRESULT AppendNewFrame(HBITMAP hBitmap); + + /// Inserts the given bitmap bits into the movie as a new Frame at the end. + /// The width, height and nBitsPerPixel are the width, height and bits per pixel + /// of the bitmap pointed to by the input pBits. + HRESULT AppendNewFrame(int nWidth, + int nHeight, + LPVOID pBits, + int nBitsPerPixel); + +private: + + void call_avi(); + +private: + static OpenGl_AVIWriter * MyAVIWriterInstance; + Standard_Boolean myIsAllowRecord; + + BYTE * mypBits; + UINT myWidth; + UINT myHeight; + + HDC myhAviDC; + HANDLE myhHeap; + HANDLE myhWindow; // window containing the OGL context + LPVOID mylpBits; // Useful to hold the bitmap content if any + LONG mylSample; // Keeps track of the current Frame Index + PAVIFILE mypAviFile; + PAVISTREAM mypAviStream; + PAVISTREAM mypAviCompressedStream; + AVISTREAMINFOW myAviStreamInfo; + AVICOMPRESSOPTIONS myAviCompressOptions; + wchar_t * myFileName; // Holds the Output Movie File Name + TCollection_AsciiString myErrMsg; // Holds the Last Error Message, if any + + int myAppendFuncSelector; //0=Dummy 1=FirstTime 2=Usual + + HRESULT AppendFrameFirstTime(HBITMAP ); + HRESULT AppendFrameUsual(HBITMAP); + HRESULT AppendDummy(HBITMAP); + HRESULT (OpenGl_AVIWriter::*pAppendFrame[3])(HBITMAP hBitmap); + + HRESULT AppendFrameBitsFirstTime(int, int, LPVOID,int ); + HRESULT AppendFrameBitsUsual(int, int, LPVOID,int ); + HRESULT AppendDummyBits(int, int, LPVOID,int ); + HRESULT (OpenGl_AVIWriter::*pAppendFrameBits[3])(int, int, LPVOID, int); + + /// Takes care of creating the memory, streams, compression options etc. + /// required for the movie + HRESULT InitMovieCreation(int nFrameWidth,int nFrameHeight,int nBitsPerPixel); + + /// Takes care of releasing the memory and movie related handles + void ReleaseMemory(); + + /// Sets the Error Message + void SetErrorMessage(const char * theErrMsg); +}; + +Standard_EXPORT void OpenGl_AVIWriter_AVIWriter(void * pp, + int nWidth, + int nHeight, + int nBitsPerPixel); + +Standard_EXPORT Standard_Boolean OpenGl_AVIWriter_AllowWriting(void * hWin); + +#endif // _MSC_VER +#endif diff --git a/src/OpenGl/OpenGl_View_Redraw.cxx b/src/OpenGl/OpenGl_View_Redraw.cxx index 5b6bb69aa6..711eae6ed5 100644 --- a/src/OpenGl/OpenGl_View_Redraw.cxx +++ b/src/OpenGl/OpenGl_View_Redraw.cxx @@ -39,6 +39,10 @@ #include #include +#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE) +#include +#endif + namespace { //! Format Frame Buffer format for logging messages. @@ -523,6 +527,24 @@ void OpenGl_View::Redraw() } } +#if defined(_WIN32) && defined(HAVE_VIDEOCAPTURE) + if (OpenGl_AVIWriter_AllowWriting(myWindow->PlatformWindow()->NativeHandle())) + { + GLint params[4]; + glGetIntegerv(GL_VIEWPORT, params); + int nWidth = params[2] & ~0x7; + int nHeight = params[3] & ~0x7; + + const int nBitsPerPixel = 24; + GLubyte* aDumpData = new GLubyte[nWidth * nHeight * nBitsPerPixel / 8]; + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glReadPixels(0, 0, nWidth, nHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, aDumpData); + OpenGl_AVIWriter_AVIWriter(aDumpData, nWidth, nHeight, nBitsPerPixel); + delete[] aDumpData; + } +#endif + if (myRenderParams.Method == Graphic3d_RM_RAYTRACING && myRenderParams.IsGlobalIlluminationEnabled) { diff --git a/src/Poly/Poly_IBuffer.cxx b/src/Poly/Poly_IBuffer.cxx new file mode 100644 index 0000000000..2d88a07eed --- /dev/null +++ b/src/Poly/Poly_IBuffer.cxx @@ -0,0 +1,546 @@ +// File: Poly_IBuffer.cxx +// Created: 15.06.07 08:32 +// Author: Alexander GRIGORIEV +// Copyright: Open CASCADE 2007 + +#include +#include +#include +#include + +#pragma warning(disable:4291) + +IMPLEMENT_STANDARD_RTTIEXT(Poly_IBuffer, Standard_Transient) + +static const Standard_Size INDEXLEN = 10; +#ifdef _DEBUG +int Poly_IBuffer::GlobalCount = 0; +#endif + +//======================================================================= +//function : GetZ +//purpose : local function +//======================================================================= + +inline Standard_Real GetZ (const Poly_IBuffer::Interval& theInt, + const Standard_Real theX) +{ + return (theInt.XZ(0).Y() + (theInt.XZ(1).Y() - theInt.XZ(0).Y()) * + (theX - theInt.XZ(0).X()) / (theInt.XZ(1).X() - theInt.XZ(0).X())); +} + +//======================================================================= +//function : Poly_IBuffer +//purpose : Constructor +//======================================================================= + +Poly_IBuffer::Poly_IBuffer (const Poly_IBuffer::Interval& theInterval, + const Standard_Real theTol, + const Handle(NCollection_BaseAllocator)& theAlloc) +{ + Init (theInterval, theTol, theAlloc); +#ifdef _DEBUG + myCount = GlobalCount++; +#endif +} + +//======================================================================= +//function : Init +//purpose : Initialization, to be used after the default constructor. +//======================================================================= + +void Poly_IBuffer::Init (const Interval& theInterval, + const Standard_Real theTol, + const Handle(NCollection_BaseAllocator)& theAlloc) +{ + clearIntervals(); + myTol = theTol; + if (theAlloc.IsNull()) + myAllocator = new NCollection_IncAllocator(1000); + else + myAllocator = theAlloc; + + myMinOrd = Precision::Infinite(); + myMaxOrd = -Precision::Infinite(); + myNIntervals = 1; + + // Create the first interval covering all possible X coordinates + Interval * pInt = &theInterval.Clone(myAllocator); + // Create the index array + myIndex = static_cast + (myAllocator->Allocate((INDEXLEN+1) * sizeof(PInterval))); + const Standard_Real anXmin = theInterval.XZ(0).X(); + const Standard_Real aXstep = (theInterval.XZ(1).X() - anXmin) / INDEXLEN; + for (Standard_Size i = 0; i <= INDEXLEN; i++) { + myIndex[i].X = Standard_Real (anXmin + i*aXstep); + myIndex[i].Int = pInt; + } +} + +//======================================================================= +//function : ~Poly_IBuffer +//purpose : Destructor +//======================================================================= + +Poly_IBuffer::~Poly_IBuffer () +{ + clearIntervals(); +} + +//======================================================================= +//function : Clone +//purpose : Create a copy of the given Interval in the given allocator. +//======================================================================= + +Poly_IBuffer::Interval& Poly_IBuffer::Interval::Clone + (const Handle(NCollection_BaseAllocator)& theAlloc, + Poly_IBuffer::Interval * theDest) const +{ + if (theDest == 0L) + theDest = new (theAlloc) Interval(myXZ[0], myXZ[1], 0UL); + else { + theDest->myXZ[0] = myXZ[0]; + theDest->myXZ[1] = myXZ[1]; + theDest->myNext = 0L; + theDest->myModID = 0UL; + theDest->U.myModX = RealLast(); + } + return * theDest; +} + +//======================================================================= +//function : NewRejectID +//purpose : Generator of unique Reject ID values. +//======================================================================= + +unsigned long Poly_IBuffer::Interval::NewRejectID () +{ + static unsigned long aValue(0UL); + aValue += 4; + return aValue; +} + +//======================================================================= +//function : IsIntersect +//purpose : Check for intersection, returns the intersection point abscissa. +// @return +// True if a modification or removal is required. The decision is based +// on 2 lower bits of myRejectID value: +// - 0 : remove this interval; +// - 1 : keep the lower abscisse part, remove the upper part; +// - 2 : keep the upper abscisse part, remove the lower part; +// - 3 : remove the middle. +//======================================================================= + +Standard_Boolean Poly_IBuffer::Interval::IsIntersect + (const Poly_IBuffer::Interval& theInt, + const Standard_Real theTol, + const unsigned long theRejectID) +{ + Standard_Boolean aRes(Standard_False); + Standard_Integer aResult (-1); + Standard_Real anAbscisse (Precision::Infinite()); + const Standard_Real anXtol[2] = { + myXZ[0].X() + theTol, + myXZ[1].X() - theTol + }; + if (theInt.myXZ[0].X() < anXtol[1] && theInt.myXZ[1].X() > anXtol[0]) { + const gp_XY aVec[3] = { + gp_XY(theInt.myXZ[0] - myXZ[0]), + gp_XY(myXZ[1] - myXZ[0]), + gp_XY(theInt.myXZ[1] - theInt.myXZ[0]) + }; + const Standard_Real aDirProd = aVec[1] ^ aVec[2]; + if (aDirProd > Precision::Intersection()) { + // Intersection coefficients + const Standard_Real fInter[2] = { + (aVec[0] ^ aVec[2]) / aDirProd, + (aVec[0] ^ aVec[1]) / aDirProd + }; + anAbscisse = (myXZ[1].X() * fInter[0] + myXZ[0].X() * (1.-fInter[0])); + if (anAbscisse > anXtol[0] && fInter[1] > 0.) + if (anAbscisse < anXtol[1] && fInter[1] < 1.) { + if (theInt.myXZ[0].X() < anXtol[0]) + aResult = 2; // keep upper abscissa + else { + anAbscisse = theInt.myXZ[0].X(); + aResult = 3; + } + } else { + if (theInt.myXZ[0].X() > anXtol[0]) { + anAbscisse = theInt.myXZ[0].X(); + if (theInt.myXZ[1].X() > anXtol[1]) + aResult = 1; // keep lower abscissa + else + aResult = 3; + } else + if (theInt.myXZ[1].X() > anXtol[1]) + aResult = 0; // remove + else { + anAbscisse = theInt.myXZ[1].X(); + aResult = 2; // keep upper abscissa + } + } + } else { + Standard_Real fInter[2] = { 2., -1. }; + if (aDirProd < -Precision::Intersection()) { + // Intersection coefficients + fInter[0] = (aVec[0] ^ aVec[2]) / aDirProd; + fInter[1] = (aVec[0] ^ aVec[1]) / aDirProd; + anAbscisse = (myXZ[1].X() * fInter[0] + myXZ[0].X() * (1.-fInter[0])); + } else if (GetZ (theInt, myXZ[0].X()) < myXZ[0].Y()) + anAbscisse = theInt.myXZ[0].X(); + + if (anAbscisse < anXtol[1] && + fInter[1] < 1.-Precision::Intersection()) + if (anAbscisse > anXtol[0] && + fInter[1] > Precision::Intersection()) + { + if (theInt.myXZ[1].X() > anXtol[1]) + aResult = 1; // keep lower abscissa + else + aResult = 3; + } else { + if (theInt.myXZ[0].X() > anXtol[0]) { + anAbscisse = theInt.myXZ[0].X(); + if (theInt.myXZ[1].X() > anXtol[1]) + aResult = 1; // keep lower abscissa + else + aResult = 3; + } else + if (theInt.myXZ[1].X() > anXtol[1]) { + aResult = 0; // remove + aRes = Standard_True; + } else { + anAbscisse = theInt.myXZ[1].X(); + aResult = 2; //keep upper abscissa + } + } + } + } + if (aResult >= 0) { + myModID = theRejectID + aResult; + U.myModX = anAbscisse; + aRes = Standard_True; + } + return aRes; +} + +//======================================================================= +//function : Trim +//purpose : Shorten the interval to the new value of Xmax. +//======================================================================= + +void Poly_IBuffer::Interval::Trim (const Standard_Real theX, + const Standard_Integer theMode) +{ + const Standard_Real aZ = GetZ(* this, theX); + switch (theMode) { + case 3: + myModID = 0UL; + case 1: + Standard_ProgramError_Raise_if + (theX - myXZ[0].X() < Precision::Confusion() || theX > myXZ[1].X(), + "Trim error"); + myXZ[1].SetCoord(theX, aZ); + break; + case 2: + Standard_ProgramError_Raise_if + (theX < myXZ[0].X() || myXZ[1].X() - theX < Precision::Confusion(), + "Trim error"); + myXZ[0].SetCoord(theX, aZ); + break; + } +} + +//======================================================================= +//function : AddInterval +//purpose : Add one interval to buffer. +//======================================================================= + +Poly_IBuffer::Interval * Poly_IBuffer::AddInterval + (const Poly_IBuffer::Interval& theInterval, + Poly_IBuffer::Interval * theStart) +{ +// Variables: +// aLastModified: Newly created interval in the buffer. It is returned by +// this method so that it can be passed as theStart +// for the next call (next interval). +// aInt: Currently checked/processed interval +// aBracket[0,1]: The first and the last in the chain of intervals where +// the modification can be done, used for local optimisation. +// pLastInt: The last non-modified interval. This pointer is used to set +// pLastInt->Next() to the newly created interval. +// isWaiting: True if there have been removed intervals, to be replaced by +// a new interval. +// aFirst.Int: Same as pLastInt. probably we can get rid of pLastInt +// aFirst.X: Beginning of the new interval + + Interval * aLastModified = 0L, * aStart; + if (theStart == 0L) + aStart = const_cast (myIndex[0].Int); + else + aStart = theStart; + Interval * anInt = aStart; + Interval * aBracket[2] = { 0L, 0L }; + unsigned long aRejectID = Interval::NewRejectID(); + Interval * pLastInt = theStart; + + // Identify the intervals that should be modified + for (; anInt; anInt = anInt->Next()) { + if (anInt->XZ(0).X() > theInterval.XZ(1).X() - myTol) + break; + if (anInt->IsIntersect (theInterval, myTol, aRejectID)) { + if (aBracket[0] == 0L) + aBracket[0] = anInt; + aBracket[1] = anInt->Next(); + const long aModMode = anInt->GetModificationID() - aRejectID; + if (aModMode == 3L) { + Interval& aNewInt = anInt->Clone(myAllocator); + anInt->Trim (anInt->GetModificationAbscisse(), aModMode); + aNewInt.myXZ[0] = anInt->XZ(1); + aNewInt.myNext = anInt->Next(); + anInt->myNext = &aNewInt; + myNIntervals++; + } + } else if (aBracket[0] == 0L) + pLastInt = anInt; + } + + // Modify the intervals + Standard_Boolean isWaiting (Standard_False); + PInterval aFirst; + aFirst.Int = theStart; + aFirst.X = aStart->XZ(0).X(); + for (anInt = aBracket[0]; anInt; anInt = anInt->Next()) { + const unsigned long aCurrentID = anInt->GetModificationID(); + if ((aCurrentID & ~0x3) != aRejectID) { + if (isWaiting) { + const Standard_Real anX[2] = { + aFirst.X, + anInt->XZ(0).X() + }; + aLastModified = addInt (theInterval, anX, aFirst.Int); + if (aStart == 0L) + aStart = aLastModified; + aLastModified->myNext = anInt; + aFirst.Int = anInt; + isWaiting = Standard_False; + } + if (anInt == aBracket[1]) + break; + pLastInt = anInt; + } else { + const long aModMode = aCurrentID - aRejectID; + switch (aModMode) { + case 0: + if (aStart == anInt) + aStart = 0L; + if (isWaiting == Standard_False) { + aFirst.Int = pLastInt; + aFirst.X = anInt->XZ(0).X(); + isWaiting = Standard_True; + } + myNHoles++; + break; + case 1: + aFirst.X = anInt->GetModificationAbscisse(); + aFirst.Int = anInt; + anInt->Trim (aFirst.X, 1); + pLastInt = anInt; + isWaiting = Standard_True; + break; + case 2: + { + if (isWaiting) + isWaiting = Standard_False; + else { + aFirst.Int = pLastInt; + aFirst.X = anInt->XZ(0).X(); + } + anInt->Trim (anInt->GetModificationAbscisse(), 2); + const Standard_Real anX[2] = { + aFirst.X, + anInt->GetModificationAbscisse() + }; + aLastModified = addInt (theInterval, anX, aFirst.Int); + if (aStart == 0L) + aStart = aLastModified; + aLastModified->myNext = anInt; + aFirst.Int = anInt; + pLastInt = anInt; + } + break; + default: + Standard_ProgramError::Raise ("Poly_IBuffer::AddInterval"); + } + } + } + if (isWaiting) { + const Standard_Real anX[2] = { + aFirst.X, + myIndex[INDEXLEN].X + }; + aLastModified = addInt (theInterval, anX, aFirst.Int); + } + return aLastModified; +} + +//======================================================================= +//function : CloseBuffer +//purpose : Called after all additions of intervals +//======================================================================= + +void Poly_IBuffer::CloseBuffer (const Standard_Boolean isFiltering) +{ + const Standard_Real aConf2 = + 0.01 * Precision::Confusion() * Precision::Confusion(); + const Standard_Real aTol2 = myTol * myTol; + Interval * pPrev = 0L, * pInt = const_cast(myIndex[0].Int); + if (pInt) { + pInt->U.myPrev = 0L; + pInt->myModID = 0UL; + pPrev = pInt; + pInt = pInt->Next(); + } + while (pInt) { + if (isFiltering && + (pPrev->myXZ[1] - pInt->myXZ[0]).SquareModulus() < aConf2) + { + const gp_XY aV0 = pInt->myXZ[1] - pPrev->myXZ[0]; + const Standard_Real aL0 = aV0.SquareModulus(); + if (aL0 > aConf2) { + const Standard_Real aVProd = aV0 ^ (pPrev->myXZ[1] - pPrev->myXZ[0]); + if (aVProd * aVProd / aL0 < aTol2) { + // extend pPrev to take place of pInt + pPrev->myXZ[1] = pInt->myXZ[1]; + pPrev->myNext = pInt->Next(); + pInt = pInt->Next(); + continue; + } + } + } + pInt->U.myPrev = pPrev; + pInt->myModID = 0UL; + pPrev = pInt; + pInt = pInt->Next(); + } +} + +//======================================================================= +//function : addInt +//purpose : Internal method, called from AddInterval() +//======================================================================= + +Poly_IBuffer::Interval * Poly_IBuffer::addInt + (const Poly_IBuffer::Interval& theInterval, + const Standard_Real theX[2], + const Poly_IBuffer::Interval * thePrevious) +{ + const gp_XY aXZ[2] = { + gp_XY(theX[0], GetZ (theInterval, theX[0])), + gp_XY(theX[1], GetZ (theInterval, theX[1])) + }; + Interval& aNewInt = theInterval.Clone(myAllocator); + aNewInt.myXZ[0] = aXZ[0]; + aNewInt.myXZ[1] = aXZ[1]; + myNIntervals++; + if (thePrevious) + const_cast(thePrevious)->myNext = &aNewInt; + else { + myIndex[0].Int = &aNewInt; + if (myMinOrd > aXZ[0].Y()) + myMinOrd = aXZ[0].Y(); + if (myMaxOrd < aXZ[0].Y()) + myMaxOrd = aXZ[0].Y(); + } + if (myMinOrd > aXZ[1].Y()) + myMinOrd = aXZ[1].Y(); + if (myMaxOrd < aXZ[1].Y()) + myMaxOrd = aXZ[1].Y(); + return &aNewInt; +} + +//======================================================================= +//function : clearIntervals +//purpose : +//======================================================================= + +void Poly_IBuffer::clearIntervals () +{ + if (myAllocator.IsNull() == Standard_False) + { + Interval * anInt = const_cast (myIndex[0].Int); + while (anInt) { + Interval * anInt0 = anInt; + anInt = anInt->Next(); + anInt0->Interval::~Interval(); + myAllocator->Free(anInt0); + } + myAllocator->Free (myIndex); + } + myIndex = 0L; + myNIntervals = 0; + myNHoles = 0; +} + +//======================================================================= +//function : Dump +//purpose : Debug facility. +//======================================================================= + +void Poly_IBuffer::Dump (Standard_OStream& theStream) +{ + const Interval * anInt = First(); + int aCount(0); + for (; anInt; anInt = anInt->Next()) { + char buf[256]; + // if (anInt->XZ(0).Y() > Precision::Infinite() * 0.1 && + // anInt->XZ(1).Y() > Precision::Infinite() * 0.1) + // continue; + sprintf (buf, "%03d (%9.5f %9.5f) - (%9.5f %9.5f)", ++aCount, + anInt->XZ(0).X(), anInt->XZ(0).Y(), + anInt->XZ(1).X(), anInt->XZ(1).Y()); + theStream << buf << endl; + } +} + +//======================================================================= +//function : DebugPolyline +//purpose : Debug facility. +//======================================================================= + +void Poly_IBuffer::DebugPolyline (Standard_OStream& theStream, + const Standard_Real theY) +{ + static int aTestCount (0); + const Interval * anInt = First(); + Standard_Real aLastVal[2] = { Precision::Infinite(), Precision::Infinite() }; + Standard_Boolean isStarted (Standard_True); + std::streamsize oldPrec = theStream.precision(8); + for (; anInt; anInt = anInt->Next()) { + if (anInt->XZ(0).Y() > Precision::Infinite() * 0.1 && + anInt->XZ(1).Y() > Precision::Infinite() * 0.1) + { + if (isStarted == Standard_False) { + theStream << endl; + isStarted = Standard_True; + } + continue; + } + if (isStarted) { + theStream << "polyline ibuf" << aTestCount++; + isStarted = Standard_False; + } + if (fabs(anInt->XZ(0).X() - aLastVal[0]) > Precision::Confusion() || + fabs(anInt->XZ(0).Y() - aLastVal[1]) > Precision::Confusion()) + theStream << " " << anInt->XZ(0).X() << ' ' + << theY << ' ' << anInt->XZ(0).Y() << ' '; + theStream << " " << anInt->XZ(1).X() << ' ' + << theY << ' ' << anInt->XZ(1).Y() << ' '; + aLastVal[0] = anInt->XZ(1).X(); + aLastVal[1] = anInt->XZ(1).Y(); + } + theStream.precision(oldPrec); + theStream << endl; +} diff --git a/src/Poly/Poly_IBuffer.hxx b/src/Poly/Poly_IBuffer.hxx new file mode 100644 index 0000000000..72ceb7d0b7 --- /dev/null +++ b/src/Poly/Poly_IBuffer.hxx @@ -0,0 +1,253 @@ +// File: Poly_IBuffer.hxx +// Created: 15.06.07 08:08 +// Author: Alexander GRIGORIEV +// Copyright: Open CASCADE 2007 + + +#ifndef Poly_IBuffer_HeaderFile +#define Poly_IBuffer_HeaderFile + +#include +#include +#include + +DEFINE_STANDARD_HANDLE (Poly_IBuffer, Standard_Transient) + +typedef NCollection_List Poly_ListOfIBuffer; + +//! Interval buffer to build outline curve on a set of polygons. +class Poly_IBuffer: public Standard_Transient +{ + public: + class Interval + { + public: + // ---------- PUBLIC METHODS ---------- + Interval (const gp_XY& theXZfirst, + const gp_XY& theXZlast, + const unsigned long theModID = 0UL); + + /** + * Allocator-based operator new for dynamic allocations + */ + DEFINE_NCOLLECTION_ALLOC + + /** + * Create a copy of the given Interval in the given allocator. + * If theDest==NULL then a new instance is created. + */ + Standard_EXPORT virtual Interval& + Clone (const Handle(NCollection_BaseAllocator)&, + Interval * theDest = NULL) const; + + /** + * Query the abscisse of the interval. + */ + const gp_XY& XZ (const Standard_Integer ind) const; + + /** + * Query the interval for modification. + */ + gp_XY& XZ (const Standard_Integer ind); + + /** + * Shorten the interval to the new value of Xmax. + */ + Standard_EXPORT void Trim (const Standard_Real theX, + const Standard_Integer theMode); + /** + * Query the previous interval in the buffer. + */ + Interval * Previous () const; + + /** + * Query the next interval in the buffer. + */ + Interval * Next () const; + + /** + * Query the RejectID indicating the modification status of the interval + */ + unsigned long GetModificationID () const; + + /** + * Query the abscisse value required for modification. + */ + Standard_Real GetModificationAbscisse() const; + + /** + * Set the modification ID. + */ + void SetModificationID (const unsigned long theValue); + + /** + * Check for intersection, returns the intersection point abscissa. + * @return + * True if a modification or removal is required. The decision is based + * on 2 lower bits of myRejectID value: + * - 0 : remove this interval; + * - 1 : keep the lower abscisse part, remove the upper part; + * - 2 : keep the upper abscisse part, remove the lower part; + * - 3 : remove the middle. + * @param theInt + * The other interval that may intersect this one. + * @param theTol + * Tolerance of intersection: smaller intersections are neglected. + * @param theRejectID + * Base ID that is stored in the interval with the corresponding + * modification status. + */ + Standard_EXPORT Standard_Boolean + IsIntersect (const Interval& theInt, + const Standard_Real theTol, + const unsigned long theRejectID); + /** + * Generator of unique Reject ID values. + */ + static Standard_EXPORT unsigned long + NewRejectID (); + + private: + // ---------- PRIVATE FIELDS ---------- + Interval * myNext; + gp_XY myXZ[2]; + union { + Standard_Real myModX; + Interval * myPrev; + } U; + unsigned long myModID; + friend class Poly_IBuffer; + }; + + public: + // ---------- PUBLIC METHODS ---------- + + /** + * Default constructor. + */ + Poly_IBuffer (); + + /** + * Constructor. + */ + Standard_EXPORT Poly_IBuffer + (const Interval& theInterval, + const Standard_Real theTol, + const Handle(NCollection_BaseAllocator)& theAlloc = 0L); + + /** + * Get the next IBuffer in the list. + */ + //inline const Poly_IBuffer& YNext() const + //{ return * myNext; } + inline const Poly_IBuffer *& YNext() + { return myNext; } + + /** + * Get the previous IBuffer in the list. + */ + //inline const Poly_IBuffer& YPrevious() const + //{ return * myPrevious; } + inline const Poly_IBuffer *& YPrevious() + { return myPrevious; } + + inline const Standard_Real MyY() const + { return myY; } + + /** + * Set myY value. + */ + inline void SetY (const Standard_Real theY) + { myY = theY; } + +#ifdef _DEBUG + inline int MyCount() + { return myCount; } +#endif + + /** + * Initialization, to be used after the default constructor. + */ + Standard_EXPORT void Init + (const Interval& theInterval, + const Standard_Real theTol, + const Handle(NCollection_BaseAllocator)& theAlloc = 0L); + + Standard_EXPORT ~Poly_IBuffer (); + + Standard_EXPORT Interval * + AddInterval (const Interval& theInterval, + Interval * theStart = 0L); + + /** + * Called when all intervals are added, just before extraction of data. + * This method sets the values 'myPrev' in all Intervals. Can be omittred + * if the method Previous() is not to be called afterwards. + * @param isFiltering + * If True then the method would merge the intervals that form a straight + * line. It can lead to loss of data attached to intervals, use this only + * when you are only interested in geometry of intervals. + */ + Standard_EXPORT void CloseBuffer (const Standard_Boolean isFiltering + = Standard_False); + + const Interval * First () const; + + void GetOrdinateExtents (Standard_Real& theMin, + Standard_Real& theMax) const; + /** + * Debug facility. + */ + Standard_EXPORT void Dump (Standard_OStream& theStream); + + /** + * Debug facility. + */ + Standard_EXPORT void DebugPolyline (Standard_OStream& theStream, + const Standard_Real theY = 1.); + + protected: + // ---------- PROTECTED METHODS ---------- + + typedef struct { + Standard_Real X; + const Interval * Int; + } PInterval; + + Interval * addInt (const Interval& theInterval, + const Standard_Real theX[2], + const Interval * thePrevious); + void clearIntervals(); + + private: + Poly_IBuffer (const Poly_IBuffer& theOther); + Poly_IBuffer& operator = (const Poly_IBuffer& theOther); + + private: + // ---------- PRIVATE FIELDS ---------- + + Handle(NCollection_BaseAllocator) myAllocator; + Standard_Real myTol; + Standard_Real myMinOrd; + Standard_Real myMaxOrd; + Standard_Size myNIntervals; + Standard_Size myNHoles; + PInterval * myIndex; + //Next IBuffer in the list + const Poly_IBuffer* myNext; + //Previous IBuffer in the list + const Poly_IBuffer* myPrevious; + Standard_Real myY; +#ifdef _DEBUG + int myCount; + static int GlobalCount; +#endif + +public: + // Declaration of CASCADE RTTI + DEFINE_STANDARD_RTTIEXT (Poly_IBuffer, Standard_Transient) +}; + +#include + +#endif diff --git a/src/Poly/Poly_IBuffer.lxx b/src/Poly/Poly_IBuffer.lxx new file mode 100644 index 0000000000..adf9c99f23 --- /dev/null +++ b/src/Poly/Poly_IBuffer.lxx @@ -0,0 +1,87 @@ +// File: Poly_IBuffer.lxx +// Created: 15.06.07 07:56 +// Author: Alexander GRIGORIEV +// Copyright: Open CASCADE 2007 + +//! Constructor. +inline Poly_IBuffer::Interval::Interval (const gp_XY& theXZfirst, + const gp_XY& theXZlast, + const unsigned long theModID) + : myNext (0L), + myModID (theModID) +{ + U.myModX = RealLast(); + myXZ[0] = theXZfirst; + myXZ[1] = theXZlast; +} + +//! Query the beginning (ind==0) or end (ind == 1) of the interval. +inline const gp_XY& Poly_IBuffer::Interval::XZ (const Standard_Integer i) const +{ + return myXZ[i&0x1]; +} + +//! Query the beginning (ind==0) or end (ind == 1) of the interval for modif +inline gp_XY& Poly_IBuffer::Interval::XZ (const Standard_Integer i) +{ + return myXZ[i&0x1]; +} + +//! Query the next interval in the buffer. +inline Poly_IBuffer::Interval * Poly_IBuffer::Interval::Next () const +{ + return myNext; +} + +//! Query the previous interval in the buffer. +inline Poly_IBuffer::Interval * Poly_IBuffer::Interval::Previous () const +{ + return U.myPrev; +} + +//! Set the modification ID. +inline void Poly_IBuffer::Interval::SetModificationID + (const unsigned long theValue) +{ + myModID = theValue; +} + +//! Query the RejectID field indicating the modification status of the interval +inline unsigned long Poly_IBuffer::Interval::GetModificationID () const +{ + return myModID; +} + +//! Query the abscisse value required for modification. +inline Standard_Real Poly_IBuffer::Interval::GetModificationAbscisse() const +{ + return U.myModX; +} + +//! Returns the head of the list of intervals. +/** Other intervals can be obtained by iterative calling Next() of each + * returned interval. + */ +inline const Poly_IBuffer::Interval * Poly_IBuffer::First () const +{ + return myIndex ? myIndex[0].Int : 0L; +} + +//! Default constructor +inline Poly_IBuffer::Poly_IBuffer() + : myTol (0.), + myMinOrd (0.), + myMaxOrd (0.), + myNIntervals(0), + myNHoles (0), + myIndex (0L) +{} + +//! Get extents of the buffer along the ordinate, excepting the +//! artificial intervals at infinite ordinate +inline void Poly_IBuffer::GetOrdinateExtents (Standard_Real& theMin, + Standard_Real& theMax) const +{ + theMin = myMinOrd; + theMax = myMaxOrd; +} diff --git a/src/SelectMgr/SelectMgr_SelectionManager.cxx b/src/SelectMgr/SelectMgr_SelectionManager.cxx index eb36f0343a..72a8ae2dc7 100644 --- a/src/SelectMgr/SelectMgr_SelectionManager.cxx +++ b/src/SelectMgr/SelectMgr_SelectionManager.cxx @@ -370,11 +370,6 @@ void SelectMgr_SelectionManager::Activate (const Handle(SelectMgr_SelectableObje if (myGlobal.Contains (theObject)) { - const Standard_Integer aGlobalSelMode = theObject->GlobalSelectionMode(); - if (theMode != aGlobalSelMode && theSelector->IsActive (theObject, aGlobalSelMode)) - { - theSelector->Deactivate (theObject->Selection (aGlobalSelMode)); - } theSelector->Activate (theObject->Selection (theMode)); } else diff --git a/src/Standard/Standard_GUID.cxx b/src/Standard/Standard_GUID.cxx index 459a60d964..158aef8eb9 100644 --- a/src/Standard/Standard_GUID.cxx +++ b/src/Standard/Standard_GUID.cxx @@ -393,10 +393,22 @@ Standard_Integer Standard_GUID::Hash(const Standard_Integer Upper) const throw Standard_RangeError("Standard_GUID::Hash: Try to apply HashCode method with negative or null argument."); } - char sguid[Standard_GUID_SIZE_ALLOC]; - ToCString(sguid); - - return ::HashCode(sguid,Upper); + // ==== AGV 16/12/2012: More optimal hash function === + //char sguid[Standard_GUID_SIZE_ALLOC]; + //ToCString(sguid); + //return ::HashCode(sguid,Upper); + // =================================================== + unsigned int aHash = ((static_cast(my8b6) << 24) | + (static_cast(my8b5) << 16) | + (static_cast(my8b4) << 8) | + (static_cast(my8b3))); + aHash = (aHash ^ (aHash >> 11)) & 0x07ffffff; + aHash = (aHash * 31 + ((static_cast(my8b2) << 24) | + (static_cast(my8b1) << 16) | + (static_cast(my16b3)))) & 0x07ffffff; + aHash = (aHash * 31 + ((static_cast(my16b2) << 16) | + (static_cast(my16b1)))) & 0x07ffffff; + return (aHash * 31 + my32b) % Upper; } Standard_Boolean Standard_GUID::IsEqual(const Standard_GUID& aGuid1,const Standard_GUID& aGuid2) diff --git a/src/StdSelect/StdSelect_Shape.cxx b/src/StdSelect/StdSelect_Shape.cxx index 5293d3706a..4850304818 100644 --- a/src/StdSelect/StdSelect_Shape.cxx +++ b/src/StdSelect/StdSelect_Shape.cxx @@ -54,7 +54,7 @@ void StdSelect_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*PM*/ else StdPrs_WFShape::Add (P, mysh, myDrawer); } - else if (aMode==0) + else StdPrs_WFShape::Add (P, mysh, myDrawer); } diff --git a/src/TDF/TDF_Label.hxx b/src/TDF/TDF_Label.hxx index 00f7522c88..ab01f019f9 100644 --- a/src/TDF/TDF_Label.hxx +++ b/src/TDF/TDF_Label.hxx @@ -117,7 +117,7 @@ public: //! Adds an Attribute to the current label. Raises if //! there is already one. - Standard_EXPORT void AddAttribute (const Handle(TDF_Attribute)& anAttribute, const Standard_Boolean append = Standard_False) const; + Standard_EXPORT void AddAttribute (const Handle(TDF_Attribute)& anAttribute, const Standard_Boolean append = Standard_True) const; //! Forgets an Attribute from the current label, //! setting its forgotten status true and its valid diff --git a/src/TDataXtd/TDataXtd_Presentation.cxx b/src/TDataXtd/TDataXtd_Presentation.cxx index 53d3d9fea6..770b8eb4f7 100644 --- a/src/TDataXtd/TDataXtd_Presentation.cxx +++ b/src/TDataXtd/TDataXtd_Presentation.cxx @@ -285,17 +285,17 @@ void TDataXtd_Presentation::SetMode(const Standard_Integer theMode) //function : SetSelectionMode //purpose : //======================================================================= -void TDataXtd_Presentation::SetSelectionMode(const Standard_Integer theSelectionMode) +void TDataXtd_Presentation::SetSelectionMode(const Standard_Integer theSelectionMode, const Standard_Boolean theTransaction) { if (! myHasOwnSelectionMode || mySelectionMode != theSelectionMode) { - Backup(); + if (theTransaction) + Backup(); mySelectionMode = theSelectionMode; myHasOwnSelectionMode = Standard_True; } } - //======================================================================= //function : MaterialIndex //purpose : diff --git a/src/TDataXtd/TDataXtd_Presentation.hxx b/src/TDataXtd/TDataXtd_Presentation.hxx index e92dc574ca..d319a9f4ec 100644 --- a/src/TDataXtd/TDataXtd_Presentation.hxx +++ b/src/TDataXtd/TDataXtd_Presentation.hxx @@ -114,7 +114,12 @@ public: Standard_EXPORT void SetMode(const Standard_Integer theMode); - Standard_EXPORT void SetSelectionMode(const Standard_Integer theSelectionMode); + //! Sets selection mode. + //! If "theTransaction" flag is OFF, modification of the attribute doesn't influence the transaction mechanism + //! (the attribute doesn't participate in undo/redo because of this modification). + //! Certainly, if any other data of the attribute is modified (display mode, color, ...), + //! the attribute will be included into undo/redo. + Standard_EXPORT void SetSelectionMode(const Standard_Integer theSelectionMode, const Standard_Boolean theTransaction = Standard_True); Standard_EXPORT Standard_Integer MaterialIndex() const; diff --git a/src/TPrsStd/TPrsStd_AISPresentation.cxx b/src/TPrsStd/TPrsStd_AISPresentation.cxx index 8297fbe035..173639ab58 100644 --- a/src/TPrsStd/TPrsStd_AISPresentation.cxx +++ b/src/TPrsStd/TPrsStd_AISPresentation.cxx @@ -591,11 +591,16 @@ Standard_Boolean TPrsStd_AISPresentation::HasOwnSelectionMode() const //function : SetSelectionMode //purpose : //======================================================================= -void TPrsStd_AISPresentation::SetSelectionMode(const Standard_Integer theSelectionMode) +void TPrsStd_AISPresentation::SetSelectionMode(const Standard_Integer theSelectionMode, const Standard_Boolean theTransaction) { - Backup(); - getData()->SetSelectionMode (theSelectionMode); - AISUpdate(); + if (theTransaction) + Backup(); + getData()->SetSelectionMode (theSelectionMode, theTransaction); + + if ( myAIS.IsNull() ) + AISUpdate(); + else + ActivateSelectionMode(); } //======================================================================= @@ -800,7 +805,7 @@ void TPrsStd_AISPresentation::AISUpdate() if ( !(anObj == myAIS) ) { if ( !aContext.IsNull() ) - aContext->Remove (myAIS, Standard_True); + aContext->Remove (myAIS, Standard_False); // Driver has built new AIS. myAIS = anObj; @@ -871,36 +876,7 @@ void TPrsStd_AISPresentation::AISUpdate() myAIS->SetDisplayMode(aMode); } - if ( !aContext.IsNull() && IsDisplayed() ) - aContext->Redisplay(myAIS, Standard_False); - - if (HasOwnSelectionMode()) { - if (!aContext.IsNull()) - { - TColStd_ListOfInteger anActivatedModes; - aContext->ActivatedModes (myAIS, anActivatedModes); - Standard_Boolean isActivated = Standard_False; - Standard_Integer aSelectionMode = SelectionMode(); - if (aSelectionMode == -1) - { - aContext->Deactivate(myAIS); - } - else - { - for (TColStd_ListIteratorOfListOfInteger aModeIter (anActivatedModes); aModeIter.More(); aModeIter.Next()) - { - if (aModeIter.Value() == aSelectionMode) - { - isActivated = Standard_True; - break; - } - } - if (!isActivated) - aContext->Activate (myAIS, aSelectionMode, Standard_False); - } - } - } - + ActivateSelectionMode(); } if (IsDisplayed() && !aContext.IsNull()) @@ -1013,3 +989,40 @@ Handle(AIS_InteractiveContext) TPrsStd_AISPresentation::getAISContext() const return Handle_AIS_InteractiveContext(); } + +//======================================================================= +//function : ActivateSelectionMode +//purpose : Activates selection mode of the interactive object. +// It is called internally on change of selection mode and AISUpdate(). +//======================================================================= +void TPrsStd_AISPresentation::ActivateSelectionMode() +{ + if (!myAIS.IsNull() && HasOwnSelectionMode()) + { + Handle(AIS_InteractiveContext) aContext = getAISContext(); + if (!aContext.IsNull()) + { + TColStd_ListOfInteger anActivatedModes; + aContext->ActivatedModes (myAIS, anActivatedModes); + Standard_Boolean isActivated = Standard_False; + Standard_Integer aSelectionMode = SelectionMode(); + if (aSelectionMode == -1) + { + aContext->Deactivate(myAIS); + } + else + { + for (TColStd_ListIteratorOfListOfInteger aModeIter (anActivatedModes); aModeIter.More(); aModeIter.Next()) + { + if (aModeIter.Value() == aSelectionMode) + { + isActivated = Standard_True; + break; + } + } + if (!isActivated) + aContext->Activate (myAIS, aSelectionMode, Standard_False); + } + } + } +} diff --git a/src/TPrsStd/TPrsStd_AISPresentation.hxx b/src/TPrsStd/TPrsStd_AISPresentation.hxx index 672ff5f9b4..2e3660cb8a 100644 --- a/src/TPrsStd/TPrsStd_AISPresentation.hxx +++ b/src/TPrsStd/TPrsStd_AISPresentation.hxx @@ -157,8 +157,13 @@ public: Standard_EXPORT void UnsetMode(); Standard_EXPORT Standard_Integer SelectionMode() const; - - Standard_EXPORT void SetSelectionMode (const Standard_Integer theSelectionMode); + + //! Sets selection mode. + //! If "theTransaction" flag is OFF, modification of the attribute doesn't influence the transaction mechanism + //! (the attribute doesn't participate in undo/redo because of this modification). + //! Certainly, if any other data of the attribute is modified (display mode, color, ...), + //! the attribute will be included into undo/redo. + Standard_EXPORT void SetSelectionMode (const Standard_Integer theSelectionMode, const Standard_Boolean theTransaction = Standard_True); Standard_EXPORT Standard_Boolean HasOwnSelectionMode() const; @@ -197,6 +202,10 @@ protected: private: Handle(AIS_InteractiveContext) getAISContext() const; + + //! Activates selection mode of the interactive object. + //! It is called internally on change of selection mode and AISUpdate(). + void ActivateSelectionMode(); //! Updates AIS_InteractiveObject stored in the attribute //! and applies the visualization settings @@ -209,7 +218,6 @@ private: //! the viewer; If = True then AISObject is removed //! from AIS_InteractiveContext instead of simple erasing in the viewer Standard_EXPORT void AISErase (const Standard_Boolean remove = Standard_False); - private: Handle(AIS_InteractiveObject) myAIS; }; diff --git a/src/VrmlData/VrmlData_ShapeConvert.cxx b/src/VrmlData/VrmlData_ShapeConvert.cxx index 151d1978b1..57a3b9f87b 100644 --- a/src/VrmlData/VrmlData_ShapeConvert.cxx +++ b/src/VrmlData/VrmlData_ShapeConvert.cxx @@ -134,6 +134,7 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, TopoDS_Shape aTestedShape; aTestedShape.TShape (aShape.TShape()); aTestedShape.Orientation (isReverse ? TopAbs_REVERSED : TopAbs_FORWARD); + Standard_Boolean isTessellate (Standard_False); switch (ShapeType[i]) { case TopAbs_FACE: { @@ -147,6 +148,16 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, break; } + if (aTri.IsNull()) + isTessellate = Standard_True; + // Check the existing deflection + else if (aTri->Deflection() > aDeflection+ Precision::Confusion()) + isTessellate = Standard_True; + if (isTessellate) { + // Triangulate the face by the standard OCC mesher + BRepMesh_IncrementalMesh IM (aFace, aDeflection, Standard_False, theDeflAngle); + aTri = BRep_Tool::Triangulation (aFace, aLoc); + } if (aTri.IsNull() == Standard_False) { TopoDS_Shape aTestedShapeRev = aTestedShape; aTestedShapeRev.Orientation (isReverse ? @@ -179,6 +190,8 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, { const TopoDS_Edge& aEdge = TopoDS::Edge (aShape); if (aEdge.IsNull() == Standard_False) { + Handle(Poly_Polygon3D) aPol = BRep_Tool::Polygon3D (aEdge, aLoc); + if (aRelMap.IsBound (aTestedShape)) { aTShapeNode = aRelMap(aTestedShape); break; @@ -191,34 +204,53 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, aTShapeNode = aRelMap(aTestedShape); break; } - - //try to find PolygonOnTriangulation - Handle(Poly_PolygonOnTriangulation) aPT; - Handle(Poly_Triangulation) aT; - TopLoc_Location aL; - BRep_Tool::PolygonOnTriangulation(aEdge, aPT, aT, aL); - - // If PolygonOnTriangulation was found -> get the Polygon3D - Handle(Poly_Polygon3D) aPol; - if(!aPT.IsNull() && !aT.IsNull() && aPT->HasParameters()) { - BRepAdaptor_Curve aCurve(aEdge); - Handle(TColStd_HArray1OfReal) aPrs = aPT->Parameters(); - Standard_Integer nbNodes = aPT->NbNodes(); - TColgp_Array1OfPnt arrNodes(1, nbNodes); - TColStd_Array1OfReal arrUVNodes(1, nbNodes); - - for(Standard_Integer j = 1; j <= nbNodes; j++) { - arrUVNodes(j) = aPrs->Value(aPrs->Lower() + j - 1); - arrNodes(j) = aCurve.Value(arrUVNodes(j)); + + if (aPol.IsNull()) + isTessellate = Standard_True; + // Check the existing deflection + else if (aPol->Deflection() > aDeflection+ Precision::Confusion() + && BRep_Tool::IsGeometric(aEdge)) + isTessellate = Standard_True; + + if (isTessellate && BRep_Tool::IsGeometric(aEdge)) { + //try to find PolygonOnTriangulation + Handle(Poly_PolygonOnTriangulation) aPT; + Handle(Poly_Triangulation) aT; + TopLoc_Location aL; + + Standard_Boolean found = Standard_False; + Standard_Integer j = 1; + for (;;) { + BRep_Tool::PolygonOnTriangulation(aEdge, aPT, aT, aL, j); + + if (aPT.IsNull() || aT.IsNull()) break; + + if (aPT->Deflection() <= aDeflection + Precision::Confusion() + && aPT->HasParameters()) + { + found = Standard_True; + break; + } + j++; } - aPol = new Poly_Polygon3D(arrNodes, arrUVNodes); - aPol->Deflection (aPT->Deflection()); - } - else { - aPol = BRep_Tool::Polygon3D(aEdge, aL); + + if(found) { - // If polygon was not found -> generate it - if (aPol.IsNull()) { + BRepAdaptor_Curve aCurve(aEdge); + Handle(TColStd_HArray1OfReal) aPrs = aPT->Parameters(); + Standard_Integer nbNodes = aPT->NbNodes(); + TColgp_Array1OfPnt arrNodes(1, nbNodes); + TColStd_Array1OfReal arrUVNodes(1, nbNodes); + + for(Standard_Integer j = 1; j <= nbNodes; j++) { + arrUVNodes(j) = aPrs->Value(aPrs->Lower() + j - 1); + arrNodes(j) = aCurve.Value(arrUVNodes(j)); + } + aPol = new Poly_Polygon3D(arrNodes, arrUVNodes); + aPol->Deflection (aPT->Deflection()); + } + else{ + BRepAdaptor_Curve aCurve(aEdge); const Standard_Real aFirst = aCurve.FirstParameter(); const Standard_Real aLast = aCurve.LastParameter(); @@ -236,11 +268,10 @@ void VrmlData_ShapeConvert::Convert (const Standard_Boolean theExtractFaces, aPol = new Poly_Polygon3D(arrNodes, arrUVNodes); aPol->Deflection (aDeflection); } + + BRep_Builder aBld; + aBld.UpdateEdge (aEdge, aPol); } - - if (aPol.IsNull()) - continue; - aTShapeNode = polToIndexedLineSet (aPol); myScene.AddNode (aTShapeNode, Standard_False); // Bind the converted face diff --git a/src/XmlMDF/XmlMDF.cxx b/src/XmlMDF/XmlMDF.cxx index d688b6de10..d8726779bd 100644 --- a/src/XmlMDF/XmlMDF.cxx +++ b/src/XmlMDF/XmlMDF.cxx @@ -256,7 +256,10 @@ Standard_Integer XmlMDF::ReadSubTree (const XmlObjMgt_Element& theElement, if (isBound) tAtt = Handle(TDF_Attribute)::DownCast(theRelocTable.Find(anID)); else + { tAtt = driver -> NewEmpty(); + tAtt->SetID(); + } if (tAtt->Label().IsNull()) theLabel.AddAttribute (tAtt); else diff --git a/src/XmlMDataStd/XmlMDataStd_ExtStringArrayDriver.cxx b/src/XmlMDataStd/XmlMDataStd_ExtStringArrayDriver.cxx index 2e0c9662b8..d53930b6be 100644 --- a/src/XmlMDataStd/XmlMDataStd_ExtStringArrayDriver.cxx +++ b/src/XmlMDataStd/XmlMDataStd_ExtStringArrayDriver.cxx @@ -24,6 +24,7 @@ #include #include #include +#include IMPLEMENT_STANDARD_RTTIEXT(XmlMDataStd_ExtStringArrayDriver,XmlMDF_ADriver) IMPLEMENT_DOMSTRING (FirstIndexString, "first") @@ -238,39 +239,46 @@ void XmlMDataStd_ExtStringArrayDriver::Paste (const Handle(TDF_Attribute)& theSo // Find a separator. Standard_Boolean found(Standard_True); - // Preferrable symbols for the separator: - _ . : ^ ~ - // Don't use a space as a separator: XML low-level parser sometimes "eats" it. + // This improvement was defined in the version 8. + // So, if the user wants to save the document under the 7th or earlier versions, + // don't apply this improvement. Standard_Character c = '-'; - static Standard_Character aPreferable[] = "-_.:^~"; - for (i = 0; found && aPreferable[i]; i++) + if (XmlLDrivers::StorageVersion() > 7) { - c = aPreferable[i]; - found = Contains(aExtStringArray, TCollection_ExtendedString(c)); - } - // If all prefferable symbols exist in the array, - // try to use any other simple symbols. - if (found) - { - c = '!'; - while (found && c < '~') + // Preferrable symbols for the separator: - _ . : ^ ~ + // Don't use a space as a separator: XML low-level parser sometimes "eats" it. + Standard_Character c = '-'; + static Standard_Character aPreferable[] = "-_.:^~"; + for (i = 0; found && aPreferable[i]; i++) + { + c = aPreferable[i]; + found = Contains(aExtStringArray, TCollection_ExtendedString(c)); + } + // If all prefferable symbols exist in the array, + // try to use any other simple symbols. + if (found) { - found = Standard_False; + c = '!'; + while (found && c < '~') + { + found = Standard_False; #ifdef _DEBUG - TCollection_AsciiString cseparator(c); // deb + TCollection_AsciiString cseparator(c); // deb #endif - TCollection_ExtendedString separator(c); - found = Contains(aExtStringArray, separator); - if (found) - { - c++; - // Skip forbidden symbols for XML. - while (c < '~' && (c == '&' || c == '<')) + TCollection_ExtendedString separator(c); + found = Contains(aExtStringArray, separator); + if (found) { c++; + // Skip forbidden symbols for XML. + while (c < '~' && (c == '&' || c == '<')) + { + c++; + } } } } - } + }// check doc version if (found) { diff --git a/src/math/math_NewtonMinimum.cxx b/src/math/math_NewtonMinimum.cxx index dd326dc1a9..76c2b8cd1b 100644 --- a/src/math/math_NewtonMinimum.cxx +++ b/src/math/math_NewtonMinimum.cxx @@ -165,15 +165,19 @@ void math_NewtonMinimum::Perform(math_MultipleVarFunctionWithHessian& F, Standard_Real aMult = RealLast(); for(Standard_Integer anIdx = 1; anIdx <= myLeft.Upper(); anIdx++) { + const Standard_Real anAbsStep = Abs(TheStep(anIdx)); + if (anAbsStep < gp::Resolution()) + continue; + if (suivant->Value(anIdx) < myLeft(anIdx)) { - Standard_Real aValue = Abs(precedent->Value(anIdx) - myLeft(anIdx)) / Abs(TheStep(anIdx)); + Standard_Real aValue = Abs(precedent->Value(anIdx) - myLeft(anIdx)) / anAbsStep; aMult = Min (aValue, aMult); } if (suivant->Value(anIdx) > myRight(anIdx)) { - Standard_Real aValue = Abs(precedent->Value(anIdx) - myRight(anIdx)) / Abs(TheStep(anIdx)); + Standard_Real aValue = Abs(precedent->Value(anIdx) - myRight(anIdx)) / anAbsStep; aMult = Min (aValue, aMult); } }