mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
Integration of OCCT 6.5.0 from SVN
This commit is contained in:
121
src/ShapeConstruct/ShapeConstruct.cdl
Executable file
121
src/ShapeConstruct/ShapeConstruct.cdl
Executable file
@@ -0,0 +1,121 @@
|
||||
-- File: ShapeConstruct.cdl
|
||||
-- Created: Tue Jul 14 09:34:35 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@pronox.nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
package ShapeConstruct
|
||||
|
||||
---Purpose: This package provides new algorithms for constructing
|
||||
-- new geometrical objects and topological shapes. It
|
||||
-- complements and extends algorithms available in Open
|
||||
-- CASCADE topological and geometrical toolkist.
|
||||
-- The functionality provided by this package are the
|
||||
-- following:
|
||||
-- projecting curves on surface,
|
||||
-- adjusting curve to have given start and end points. P
|
||||
uses
|
||||
gp,
|
||||
Geom,
|
||||
GeomAbs,
|
||||
Geom2d,
|
||||
TColgp,
|
||||
TColStd,
|
||||
ShapeExtend,
|
||||
ShapeAnalysis,
|
||||
Convert,
|
||||
BRepBuilderAPI,
|
||||
TopoDS,
|
||||
TopAbs,
|
||||
TopTools
|
||||
|
||||
is
|
||||
|
||||
class Curve;
|
||||
---Purpose: Tool for adjusting 3d and 2d curve
|
||||
|
||||
class ProjectCurveOnSurface;
|
||||
---Purpose: Tool for computing pcurve by projecting 3d curve on a surface
|
||||
---WARNING: The following two classes are just a copy of those from GEOMLITE
|
||||
-- They must be removed as soon as bug in them is fixed
|
||||
|
||||
class CompBezierCurvesToBSplineCurve;
|
||||
---Purpose: Converts a list of connecting BezierCurves
|
||||
-- into a B-spline curve.
|
||||
|
||||
class CompBezierCurves2dToBSplineCurve2d;
|
||||
---Purpose: Converts a list of connecting BezierCurves
|
||||
-- into a B-spline curve.
|
||||
|
||||
class MakeTriangulation;
|
||||
---Purpose: Tool for wire triangulation
|
||||
|
||||
ConvertCurveToBSpline(C3D : Curve from Geom;
|
||||
First : Real;
|
||||
Last : Real;
|
||||
Tol3d : Real; -- this and following parameters are used only if approximator have to be used.
|
||||
Continuity : Shape from GeomAbs;
|
||||
MaxSegments: Integer;
|
||||
MaxDegree : Integer)
|
||||
returns BSplineCurve from Geom;
|
||||
|
||||
ConvertCurveToBSpline(C2D : Curve from Geom2d;
|
||||
First : Real;
|
||||
Last : Real;
|
||||
Tol2d : Real; -- this and following parameters are used only if approximator have to be used.
|
||||
Continuity : Shape from GeomAbs;
|
||||
MaxSegments: Integer;
|
||||
MaxDegree : Integer)
|
||||
returns BSplineCurve from Geom2d;
|
||||
|
||||
ConvertSurfaceToBSpline(surf : Surface from Geom;
|
||||
UF,UL,VF,VL: Real;
|
||||
Tol3d : Real; -- this and following parameters are used only if approximator have to be used.
|
||||
Continuity : Shape from GeomAbs;
|
||||
MaxSegments: Integer;
|
||||
MaxDegree : Integer)
|
||||
returns BSplineSurface from Geom;
|
||||
|
||||
JoinPCurves(theEdges : HSequenceOfShape from TopTools;
|
||||
theFace : Face from TopoDS;
|
||||
theEdge : in out Edge from TopoDS)
|
||||
returns Boolean from Standard;
|
||||
---Purpose: join pcurves of the <theEdge> on the <theFace>
|
||||
-- try to use pcurves from originas edges <theEdges>
|
||||
-- Returns false if cannot join pcurves
|
||||
|
||||
JoinCurves(c3d1,ac3d2 : Curve from Geom;
|
||||
Orient1, Orient2 : Orientation from TopAbs;
|
||||
first1,last1,first2,last2 : in out Real;
|
||||
c3dOut : out Curve from Geom;
|
||||
isRev1,isRev2 : out Boolean) returns Boolean;
|
||||
|
||||
--- Purpose:Method for joininig curves 3D.
|
||||
-- Parameters : c3d1,ac3d2 - initial curves
|
||||
-- Orient1, Orient2 - initial edges orientations.
|
||||
-- first1,last1,first2,last2 - parameters for trimming curves
|
||||
-- (re-calculate with account of orientation edges)
|
||||
-- c3dOut - result curve
|
||||
-- isRev1,isRev2 - out parameters indicative on possible errors.
|
||||
-- Return value : True - if curves were joined successfully,
|
||||
-- else - False.
|
||||
|
||||
JoinCurves(c2d1,ac2d2 : Curve from Geom2d;
|
||||
Orient1, Orient2 : Orientation from TopAbs;
|
||||
first1,last1,first2,last2 : in out Real;
|
||||
c2dOut : out Curve from Geom2d;
|
||||
isRev1,isRev2 : out Boolean;
|
||||
isError : Boolean = Standard_False) returns Boolean;
|
||||
|
||||
--- Purpose:Method for joininig curves 3D.
|
||||
-- Parameters : c3d1,ac3d2 - initial curves
|
||||
-- Orient1, Orient2 - initial edges orientations.
|
||||
-- first1,last1,first2,last2 - parameters for trimming curves
|
||||
-- (re-calculate with account of orientation edges)
|
||||
-- c3dOut - result curve
|
||||
-- isRev1,isRev2 - out parameters indicative on possible errors.
|
||||
-- isError - input parameter indicative possible errors due to that one from edges have one vertex
|
||||
-- Return value : True - if curves were joined successfully,
|
||||
-- else - False.
|
||||
end ShapeConstruct;
|
555
src/ShapeConstruct/ShapeConstruct.cxx
Executable file
555
src/ShapeConstruct/ShapeConstruct.cxx
Executable file
@@ -0,0 +1,555 @@
|
||||
// File: ShapeConstruct.cxx
|
||||
// Created: Thu Jun 17 16:21:27 1999
|
||||
// Author: data exchange team
|
||||
// <det@lenox>
|
||||
|
||||
|
||||
#include <ShapeConstruct.ixx>
|
||||
#include <Standard_Failure.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Geom_Conic.hxx>
|
||||
#include <Geom_TrimmedCurve.hxx>
|
||||
#include <GeomConvert_ApproxCurve.hxx>
|
||||
#include <GeomConvert.hxx>
|
||||
#include <Geom2d_Conic.hxx>
|
||||
#include <Geom2d_TrimmedCurve.hxx>
|
||||
#include <Geom2dConvert_ApproxCurve.hxx>
|
||||
#include <Geom2dConvert.hxx>
|
||||
#include <Geom_RectangularTrimmedSurface.hxx>
|
||||
#include <Geom_SurfaceOfLinearExtrusion.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <TColgp_Array2OfPnt.hxx>
|
||||
#include <TColStd_Array2OfReal.hxx>
|
||||
#include <GeomConvert_ApproxSurface.hxx>
|
||||
#include <Geom_SurfaceOfRevolution.hxx>
|
||||
#include <Geom_OffsetCurve.hxx>
|
||||
#include <ShapeConstruct_Curve.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <GeomConvert_CompCurveToBSplineCurve.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <GeomAPI.hxx>
|
||||
#include <TopTools_HSequenceOfShape.hxx>
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <TopAbs_Orientation.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : ConvertCurveToBSpline
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(Geom_BSplineCurve) ShapeConstruct::ConvertCurveToBSpline(const Handle(Geom_Curve)& C3D,
|
||||
const Standard_Real First,
|
||||
const Standard_Real Last,
|
||||
const Standard_Real Tol3d,
|
||||
const GeomAbs_Shape Continuity,
|
||||
const Standard_Integer MaxSegments,
|
||||
const Standard_Integer MaxDegree)
|
||||
{
|
||||
Standard_Integer MaxDeg = MaxDegree;
|
||||
Handle(Geom_BSplineCurve) aBSpline;
|
||||
if(C3D->IsKind(STANDARD_TYPE(Geom_BSplineCurve)))
|
||||
aBSpline = Handle(Geom_BSplineCurve)::DownCast(C3D);
|
||||
else {
|
||||
if(C3D->IsKind(STANDARD_TYPE(Geom_Conic)))
|
||||
MaxDeg = Min(MaxDeg,6);
|
||||
|
||||
Handle(Geom_TrimmedCurve) tcurve = new Geom_TrimmedCurve(C3D,First,Last); //protection agains parabols ets
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
GeomConvert_ApproxCurve approx (tcurve, Tol3d, Continuity, MaxSegments, MaxDeg);
|
||||
if ( approx.HasResult() )
|
||||
aBSpline = Handle(Geom_BSplineCurve)::DownCast(approx.Curve());
|
||||
else
|
||||
aBSpline = GeomConvert::CurveToBSplineCurve(C3D,Convert_QuasiAngular);
|
||||
}
|
||||
catch (Standard_Failure) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: GeomConvert_ApproxSurface Exception: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
aBSpline = GeomConvert::CurveToBSplineCurve(C3D,Convert_QuasiAngular);
|
||||
}
|
||||
}
|
||||
return aBSpline;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ConvertCurveToBSpline
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(Geom2d_BSplineCurve) ShapeConstruct::ConvertCurveToBSpline(const Handle(Geom2d_Curve)& C2D,
|
||||
const Standard_Real First,
|
||||
const Standard_Real Last,
|
||||
const Standard_Real Tol2d,
|
||||
const GeomAbs_Shape Continuity,
|
||||
const Standard_Integer MaxSegments,
|
||||
const Standard_Integer MaxDegree)
|
||||
{
|
||||
Handle(Geom2d_BSplineCurve) aBSpline2d;
|
||||
if(C2D->IsKind(STANDARD_TYPE(Geom2d_Conic))) {
|
||||
Handle(Geom2d_TrimmedCurve) tcurve = new Geom2d_TrimmedCurve(C2D,First,Last); //protection agains parabols ets
|
||||
Geom2dConvert_ApproxCurve approx (tcurve, Tol2d, Continuity, MaxSegments, MaxDegree);
|
||||
if ( approx.HasResult() )
|
||||
aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(approx.Curve());
|
||||
else
|
||||
aBSpline2d = Geom2dConvert::CurveToBSplineCurve(tcurve,Convert_QuasiAngular);
|
||||
}
|
||||
else if(!C2D->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
|
||||
aBSpline2d = Geom2dConvert::CurveToBSplineCurve(C2D,Convert_QuasiAngular);
|
||||
}
|
||||
else
|
||||
aBSpline2d = Handle(Geom2d_BSplineCurve)::DownCast(C2D);
|
||||
|
||||
return aBSpline2d;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ConvertSurfaceToBSpline
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
// Note: this method has the same purpose as GeomConvert::SurfaceToBSplineSurface(),
|
||||
// but treats more correctly offset surfaces and takes parameters such as UV limits
|
||||
// and degree as arguments instead of deducing them from the surface.
|
||||
// Eventually it may be merged back to GeomConvert.
|
||||
|
||||
Handle(Geom_BSplineSurface) ShapeConstruct::ConvertSurfaceToBSpline(const Handle(Geom_Surface)& surf,
|
||||
const Standard_Real UF,
|
||||
const Standard_Real UL,
|
||||
const Standard_Real VF,
|
||||
const Standard_Real VL,
|
||||
const Standard_Real Tol3d,
|
||||
const GeomAbs_Shape Continuity,
|
||||
const Standard_Integer MaxSegments,
|
||||
const Standard_Integer MaxDegree)
|
||||
{
|
||||
Handle(Geom_BSplineSurface) res;
|
||||
|
||||
Handle(Geom_Surface) S = surf;
|
||||
if(surf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
|
||||
Handle(Geom_RectangularTrimmedSurface) RTS =
|
||||
Handle(Geom_RectangularTrimmedSurface)::DownCast(surf);
|
||||
S = RTS->BasisSurface();
|
||||
}
|
||||
|
||||
// use GeomConvert for direct conversion of analytic surfaces
|
||||
if (S->IsKind(STANDARD_TYPE(Geom_ElementarySurface)))
|
||||
{
|
||||
Handle(Geom_RectangularTrimmedSurface) aRTS =
|
||||
new Geom_RectangularTrimmedSurface(S,UF,UL,VF,VL);
|
||||
return GeomConvert::SurfaceToBSplineSurface(aRTS);
|
||||
}
|
||||
|
||||
if(S->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
|
||||
Handle(Geom_SurfaceOfLinearExtrusion) extr = Handle(Geom_SurfaceOfLinearExtrusion)::DownCast(S);
|
||||
Handle(Geom_Curve) basis = extr->BasisCurve();
|
||||
//gp_Dir direction = extr->Direction(); // direction not used (skl)
|
||||
|
||||
GeomAbs_Shape cnt = (Continuity > GeomAbs_C2 ? GeomAbs_C2: Continuity);
|
||||
Handle(Geom_BSplineCurve) bspl = ConvertCurveToBSpline(basis, UF, UL, Tol3d, cnt, MaxSegments, MaxDegree);
|
||||
|
||||
gp_Trsf shiftF,shiftL;
|
||||
shiftF.SetTranslation(extr->Value(UF,0),extr->Value(UF,VF));
|
||||
shiftL.SetTranslation(extr->Value(UF,0),extr->Value(UF,VL));
|
||||
|
||||
Standard_Integer nbPoles = bspl->NbPoles();
|
||||
TColgp_Array1OfPnt poles(1,nbPoles);
|
||||
TColStd_Array1OfReal weights(1,nbPoles);
|
||||
Standard_Integer nbKnots = bspl->NbKnots();
|
||||
TColStd_Array1OfReal knots(1,nbKnots);
|
||||
TColStd_Array1OfInteger mults(1,nbKnots);
|
||||
|
||||
bspl->Poles(poles);
|
||||
bspl->Knots(knots);
|
||||
bspl->Multiplicities(mults);
|
||||
bspl->Weights(weights);
|
||||
|
||||
TColgp_Array2OfPnt resPoles(1,nbPoles,1,2);
|
||||
TColStd_Array2OfReal resWeigth(1,nbPoles,1,2);
|
||||
for(Standard_Integer j = 1; j <= nbPoles; j++) {
|
||||
resPoles(j,1) = poles(j).Transformed(shiftF);
|
||||
resPoles(j,2) = poles(j).Transformed(shiftL);
|
||||
resWeigth(j,1)= weights(j);
|
||||
resWeigth(j,2)= weights(j);
|
||||
}
|
||||
|
||||
TColStd_Array1OfReal vknots(1,2);
|
||||
TColStd_Array1OfInteger vmults(1,2);
|
||||
vknots(1) = VF;
|
||||
vknots(2) = VL;
|
||||
vmults(1) = vmults(2) = 2;
|
||||
|
||||
Handle(Geom_BSplineSurface) bspline = new Geom_BSplineSurface(resPoles, resWeigth, knots, vknots, mults, vmults,
|
||||
bspl->Degree(),1,bspl->IsPeriodic(),Standard_False);
|
||||
return bspline;
|
||||
}
|
||||
|
||||
if(S->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
|
||||
Handle(Geom_SurfaceOfRevolution) revol = Handle(Geom_SurfaceOfRevolution)::DownCast(S);
|
||||
Handle(Geom_Curve) basis = revol->BasisCurve();
|
||||
if(basis->IsKind(STANDARD_TYPE(Geom_OffsetCurve))) {
|
||||
GeomAbs_Shape cnt = basis->Continuity();
|
||||
cnt = (cnt > GeomAbs_C2 ? GeomAbs_C2: cnt);
|
||||
Handle(Geom_BSplineCurve) bspl = ConvertCurveToBSpline(basis, VF, VL, Tol3d, cnt, MaxSegments, MaxDegree);
|
||||
gp_Ax1 axis = revol->Axis();
|
||||
Handle(Geom_SurfaceOfRevolution) newRevol = new Geom_SurfaceOfRevolution(bspl,axis);
|
||||
#ifdef DEB
|
||||
cout <<" Revolution on offset converted" << endl;
|
||||
#endif
|
||||
S = newRevol;
|
||||
}
|
||||
}
|
||||
|
||||
Handle(Geom_RectangularTrimmedSurface) aSurface = new Geom_RectangularTrimmedSurface(S,UF,UL,VF,VL);
|
||||
Handle(Geom_BSplineSurface) errSpl;
|
||||
for(Standard_Integer cnt = (Continuity > GeomAbs_C3 ? GeomAbs_C3: Continuity); cnt >= 0 ; ) {
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
GeomAbs_Shape aCont = (GeomAbs_Shape) cnt;
|
||||
GeomConvert_ApproxSurface anApprox(aSurface,Tol3d/2,aCont,aCont,MaxDegree,MaxDegree,MaxSegments,0);
|
||||
Standard_Boolean Done = anApprox.IsDone();
|
||||
if (anApprox.MaxError() <= Tol3d && Done) {
|
||||
|
||||
#ifdef DEB
|
||||
Standard_Integer nbOfSpan = (anApprox.Surface()->NbUKnots()-1)*(anApprox.Surface()->NbVKnots()-1);
|
||||
cout << "\terror = " << anApprox.MaxError() << "\tspans = " << nbOfSpan << endl;
|
||||
cout << " Surface is aproximated with continuity " << (GeomAbs_Shape)cnt <<endl;
|
||||
#endif
|
||||
S = anApprox.Surface();
|
||||
Handle(Geom_BSplineSurface) Bsc = Handle(Geom_BSplineSurface)::DownCast(S);
|
||||
return Bsc;
|
||||
}
|
||||
else {
|
||||
if(anApprox.HasResult())
|
||||
errSpl = Handle(Geom_BSplineSurface)::DownCast(anApprox.Surface());
|
||||
#ifdef DEB
|
||||
cout << "\terror = " << anApprox.MaxError() <<endl;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
catch (Standard_Failure) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: GeomConvert_ApproxSurface Exception: try to decrease continuity ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
if(cnt > 0) cnt--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return errSpl;
|
||||
}
|
||||
//=======================================================================
|
||||
//function : JoinPCurves
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeConstruct::JoinPCurves(const Handle(TopTools_HSequenceOfShape)& edges,
|
||||
const TopoDS_Face& theFace,
|
||||
TopoDS_Edge& theEdge)
|
||||
{
|
||||
ShapeAnalysis_Edge sae;
|
||||
BRep_Builder B;
|
||||
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
// check if current face is plane.
|
||||
Handle(Geom_Surface) aGeomSurf = BRep_Tool::Surface(theFace);
|
||||
while (aGeomSurf->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface)))
|
||||
{
|
||||
|
||||
aGeomSurf = Handle(Geom_RectangularTrimmedSurface)::DownCast(aGeomSurf)->BasisSurface();
|
||||
}
|
||||
if (aGeomSurf->IsKind(STANDARD_TYPE(Geom_Plane)))
|
||||
return Standard_True;
|
||||
|
||||
|
||||
Standard_Boolean IsEdgeSeam = Standard_False;
|
||||
Handle(Geom2d_Curve) aCrvRes1, aCrvRes2;
|
||||
TopAbs_Orientation resOrient;
|
||||
Standard_Real newf,newl;
|
||||
// iterates on edges
|
||||
Standard_Integer i = 1;
|
||||
for(; i <= edges->Length(); i++) {
|
||||
TopoDS_Edge Edge = TopoDS::Edge(edges->Value(i));
|
||||
if (i == 1)
|
||||
IsEdgeSeam = sae.IsSeam(Edge,theFace);
|
||||
else if (IsEdgeSeam && (!sae.IsSeam(Edge,theFace)))
|
||||
break; // different cases
|
||||
else if (!IsEdgeSeam && (sae.IsSeam(Edge,theFace)))
|
||||
break; // different cases
|
||||
|
||||
resOrient = TopAbs_FORWARD;
|
||||
Handle(Geom2d_Curve) c2d,c2d2;
|
||||
Standard_Real first, last,first2, last2;
|
||||
if(!sae.PCurve ( Edge, theFace, c2d, first, last, Standard_False ))
|
||||
break;
|
||||
|
||||
if(IsEdgeSeam) {
|
||||
TopoDS_Edge tmpE1 =TopoDS::Edge(Edge.Reversed());
|
||||
sae.PCurve ( tmpE1, theFace, c2d2, first2, last2, Standard_False );
|
||||
}
|
||||
|
||||
if( i == 1) {
|
||||
aCrvRes1 = c2d;
|
||||
if(IsEdgeSeam) {
|
||||
aCrvRes2 = c2d2;
|
||||
}
|
||||
newf = first;
|
||||
newl = last;
|
||||
resOrient = Edge.Orientation();
|
||||
}
|
||||
else {
|
||||
Handle(Geom2d_Curve) newCrv;
|
||||
Standard_Boolean isRev1,isRev2;
|
||||
if(!JoinCurves(aCrvRes1,c2d,resOrient,Edge.Orientation(),newf,newl,first, last,newCrv,isRev1,isRev2))
|
||||
break;
|
||||
|
||||
if(IsEdgeSeam) {
|
||||
Handle(Geom2d_Curve) newCrv2;
|
||||
Standard_Real newf2 = newf,newl2 = newl;
|
||||
|
||||
if(!JoinCurves(aCrvRes2,c2d2,resOrient,Edge.Orientation(),newf2,newl2,first2, last2,newCrv2,isRev1,isRev2))
|
||||
break;
|
||||
aCrvRes2 = newCrv2;
|
||||
}
|
||||
aCrvRes1 = newCrv;
|
||||
Standard_Real fp2d = newCrv->FirstParameter();
|
||||
Standard_Real lp2d = newCrv->LastParameter();
|
||||
newl += (last - first);
|
||||
if(fp2d > newf) newf = fp2d;
|
||||
if(lp2d < newl) newl = lp2d;
|
||||
|
||||
}
|
||||
}
|
||||
if (IsEdgeSeam)
|
||||
B.UpdateEdge(theEdge,aCrvRes1,aCrvRes2,theFace,0);
|
||||
else
|
||||
B.UpdateEdge(theEdge,aCrvRes1,theFace,0);
|
||||
B.Range(theEdge,theFace,newf,newl);
|
||||
B.SameRange(theEdge,Standard_False);
|
||||
B.SameParameter(theEdge,Standard_False);
|
||||
return (i <= edges->Length());
|
||||
}
|
||||
catch ( Standard_Failure ) {
|
||||
#ifdef DEB
|
||||
cout<<"Error: ShapeConstruct::JoinPCurves Exception in GeomConvert_CompCurveToBSplineCurve: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout<<endl;
|
||||
#endif
|
||||
}
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : JoinCurves
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
template<class HCurve>
|
||||
static inline HCurve GetCurveCopy(const HCurve& curve,
|
||||
Standard_Real& first, Standard_Real& last,
|
||||
const TopAbs_Orientation &orient)
|
||||
{
|
||||
if ( orient == TopAbs_REVERSED ) {
|
||||
Standard_Real cf = first;
|
||||
first = curve->ReversedParameter ( last );
|
||||
last = curve->ReversedParameter ( cf );
|
||||
return curve->Reversed();
|
||||
}
|
||||
return HCurve::DownCast(curve->Copy());
|
||||
}
|
||||
|
||||
template<class HCurve>
|
||||
static inline void SegmentCurve (HCurve& curve,
|
||||
const Standard_Real first,
|
||||
const Standard_Real last)
|
||||
{
|
||||
if(curve->FirstParameter() < first - Precision::PConfusion() ||
|
||||
curve->LastParameter() > last + Precision::PConfusion()) {
|
||||
if(curve->IsPeriodic())
|
||||
curve->Segment(first,last);
|
||||
else curve->Segment(Max(curve->FirstParameter(),first),
|
||||
Min(curve->LastParameter(),last));
|
||||
}
|
||||
}
|
||||
|
||||
template<class HPoint>
|
||||
static inline void GetReversedParameters(const HPoint& p11,
|
||||
const HPoint& p12,
|
||||
const HPoint& p21,
|
||||
const HPoint& p22,
|
||||
Standard_Boolean& isRev1,
|
||||
Standard_Boolean& isRev2)
|
||||
{
|
||||
isRev1 = Standard_False;
|
||||
isRev2 = Standard_False;
|
||||
//gka protection against crossing seem on second face
|
||||
|
||||
Standard_Real d11 = p11.Distance(p21);
|
||||
Standard_Real d21 =p12.Distance(p21);
|
||||
|
||||
Standard_Real d12 = p11.Distance(p22);
|
||||
Standard_Real d22 = p22.Distance(p12);
|
||||
Standard_Real Dmin1 = Min(d11,d21);
|
||||
Standard_Real Dmin2 = Min(d12,d22);
|
||||
if(fabs(Dmin1 - Dmin2) <= Precision::Confusion() || Dmin2 > Dmin1) {
|
||||
isRev1 = (d11 < d21 ? Standard_True : Standard_False);
|
||||
}
|
||||
else if(Dmin2 < Dmin1) {
|
||||
isRev1 = (d12 < d22 ? Standard_True : Standard_False);
|
||||
isRev2 = Standard_True;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//=======================================================================
|
||||
//function : JoinCurves
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeConstruct::JoinCurves(const Handle(Geom_Curve)& ac3d1,
|
||||
const Handle(Geom_Curve)& ac3d2,
|
||||
const TopAbs_Orientation Orient1,
|
||||
const TopAbs_Orientation Orient2,
|
||||
Standard_Real& first1,
|
||||
Standard_Real& last1,
|
||||
Standard_Real& first2,
|
||||
Standard_Real& last2,
|
||||
Handle(Geom_Curve)& c3dOut,
|
||||
Standard_Boolean& isRev1,
|
||||
Standard_Boolean& isRev2)
|
||||
|
||||
{
|
||||
Handle(Geom_Curve) c3d1,c3d2;
|
||||
|
||||
c3d1 = GetCurveCopy ( ac3d1, first1, last1, Orient1 );
|
||||
c3d2 = GetCurveCopy ( ac3d2, first2, last2, Orient2 );
|
||||
ShapeConstruct_Curve scc;
|
||||
Standard_Boolean After = Standard_True;
|
||||
Handle(Geom_BSplineCurve) bsplc1 = scc.ConvertToBSpline(c3d1,first1, last1,Precision::Confusion());
|
||||
Handle(Geom_BSplineCurve) bsplc2 = scc.ConvertToBSpline(c3d2,first2, last2,Precision::Confusion());
|
||||
// newf = first1;
|
||||
// newl = last1 + last2 - first2;
|
||||
|
||||
if(bsplc1.IsNull() || bsplc2.IsNull()) return Standard_False;
|
||||
|
||||
SegmentCurve(bsplc1,first1, last1);
|
||||
SegmentCurve(bsplc2,first2, last2);
|
||||
|
||||
//regression on file 866026_M-f276-f311.brep bug OCC482
|
||||
gp_Pnt pp11 = bsplc1->Pole(1);
|
||||
gp_Pnt pp12 = bsplc1->Pole(bsplc1->NbPoles());
|
||||
|
||||
gp_Pnt pp21 = bsplc2->Pole(1);
|
||||
gp_Pnt pp22 = bsplc2->Pole(bsplc2->NbPoles());
|
||||
|
||||
GetReversedParameters(pp11,pp12,pp21,pp22,isRev1,isRev2);
|
||||
|
||||
if(isRev1) {
|
||||
bsplc1->Reverse();
|
||||
}
|
||||
if(isRev2)
|
||||
bsplc2->Reverse();
|
||||
|
||||
gp_Pnt pmid = 0.5 * ( bsplc1->Pole(bsplc1->NbPoles()).XYZ() + bsplc2->Pole(1).XYZ() );
|
||||
bsplc1->SetPole(bsplc1->NbPoles(), pmid);
|
||||
bsplc2->SetPole(1, pmid);
|
||||
GeomConvert_CompCurveToBSplineCurve connect3d(bsplc1);
|
||||
if(!connect3d.Add(bsplc2,Precision::Confusion(), After, Standard_False)) return Standard_False;
|
||||
c3dOut = connect3d.BSplineCurve();
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : JoinCurves2d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeConstruct::JoinCurves(const Handle(Geom2d_Curve)& aC2d1,
|
||||
const Handle(Geom2d_Curve)& aC2d2,
|
||||
const TopAbs_Orientation Orient1,
|
||||
const TopAbs_Orientation Orient2,
|
||||
Standard_Real& first1,
|
||||
Standard_Real& last1,
|
||||
Standard_Real& first2,
|
||||
Standard_Real& last2,
|
||||
Handle(Geom2d_Curve)& C2dOut,
|
||||
Standard_Boolean& isRev1,
|
||||
Standard_Boolean& isRev2,
|
||||
const Standard_Boolean isError)
|
||||
{
|
||||
Handle(Geom2d_Curve) c2d1,c2d2;
|
||||
c2d1 = GetCurveCopy ( aC2d1, first1, last1, Orient1 );
|
||||
c2d2 = GetCurveCopy ( aC2d2, first2, last2, Orient2 );
|
||||
ShapeConstruct_Curve scc;
|
||||
Standard_Boolean After = Standard_True;
|
||||
|
||||
Handle(Geom2d_BSplineCurve) bsplc12d = scc.ConvertToBSpline(c2d1,first1,last1,Precision::Confusion());
|
||||
Handle(Geom2d_BSplineCurve) bsplc22d = scc.ConvertToBSpline(c2d2,first2,last2,Precision::Confusion());
|
||||
|
||||
if(bsplc12d.IsNull() || bsplc22d.IsNull()) return Standard_False;
|
||||
|
||||
SegmentCurve(bsplc12d,first1,last1);
|
||||
SegmentCurve(bsplc22d,first2,last2);
|
||||
//gka protection against crossing seem on second face
|
||||
gp_Pnt2d pp112d = bsplc12d->Pole(1).XY();
|
||||
gp_Pnt2d pp122d = bsplc12d->Pole(bsplc12d->NbPoles()).XY();
|
||||
|
||||
gp_Pnt2d pp212d = bsplc22d->Pole(1).XY();
|
||||
gp_Pnt2d pp222d = bsplc22d->Pole(bsplc22d->NbPoles()).XY();
|
||||
|
||||
GetReversedParameters(pp112d,pp122d,pp212d,pp222d,isRev1,isRev2);
|
||||
|
||||
//regression on file 866026_M-f276-f311.brep bug OCC482
|
||||
//if(isRev1 || isRev2)
|
||||
// return newedge1;
|
||||
if(isRev1) {
|
||||
bsplc12d->Reverse();
|
||||
}
|
||||
if(isRev2)
|
||||
bsplc22d->Reverse();
|
||||
|
||||
|
||||
//---------------------------------------------------------
|
||||
//protection against invalid topology Housing(sam1296.brep(face 707) - bugmergeedges4.brep)
|
||||
if(isError) {
|
||||
gp_Pnt2d pp1 = bsplc12d->Value(bsplc12d->FirstParameter());
|
||||
gp_Pnt2d pp2 = bsplc12d->Value(bsplc12d->LastParameter());
|
||||
gp_Pnt2d pp3 = bsplc12d->Value((bsplc12d->FirstParameter() + bsplc12d->LastParameter())*0.5);
|
||||
|
||||
Standard_Real leng = pp1.Distance(pp2);
|
||||
Standard_Boolean isCircle = (leng < pp1.Distance(pp3) + Precision::PConfusion());
|
||||
if((pp1.Distance(bsplc22d->Pole(1)) < leng) && !isCircle) return Standard_False;
|
||||
}
|
||||
//-------------------------------------------------------
|
||||
gp_Pnt2d pmid1 = 0.5 * ( bsplc12d->Pole(bsplc12d->NbPoles()).XY() + bsplc22d->Pole(1).XY() );
|
||||
bsplc12d->SetPole(bsplc12d->NbPoles(), pmid1);
|
||||
bsplc22d->SetPole(1, pmid1);
|
||||
|
||||
// abv 01 Sep 99: Geom2dConvert ALWAYS performs reparametrisation of the
|
||||
// second curve before merging; this is quite not suitable
|
||||
// Use 3d tool instead
|
||||
// Geom2dConvert_CompCurveToBSplineCurve connect2d(bsplc12d);
|
||||
gp_Pnt vPnt(0,0,0);
|
||||
gp_Vec vDir(0,0,1);
|
||||
gp_Pln vPln ( vPnt, vDir );
|
||||
Handle(Geom_BSplineCurve) bspl1 =
|
||||
Handle(Geom_BSplineCurve)::DownCast ( GeomAPI::To3d ( bsplc12d, vPln ) );
|
||||
Handle(Geom_BSplineCurve) bspl2 =
|
||||
Handle(Geom_BSplineCurve)::DownCast ( GeomAPI::To3d ( bsplc22d, vPln ) );
|
||||
GeomConvert_CompCurveToBSplineCurve connect2d(bspl1);
|
||||
if(!connect2d.Add(bspl2,Precision::PConfusion(), After, Standard_False)) return Standard_False;
|
||||
C2dOut = GeomAPI::To2d ( connect2d.BSplineCurve(), vPln );
|
||||
|
||||
return Standard_True;
|
||||
}
|
73
src/ShapeConstruct/ShapeConstruct_CompBezierCurves2dToBSplineCurve2d.cdl
Executable file
73
src/ShapeConstruct/ShapeConstruct_CompBezierCurves2dToBSplineCurve2d.cdl
Executable file
@@ -0,0 +1,73 @@
|
||||
-- File: ShapeConstruct_CompBezierCurves2dToBSplineCurve2d.cdl
|
||||
-- Created: Tue Nov 9 10:52:26 1993
|
||||
-- Author: Modelistation
|
||||
-- <model@topsn3>
|
||||
---Copyright: Matra Datavision 1993
|
||||
|
||||
class CompBezierCurves2dToBSplineCurve2d from ShapeConstruct
|
||||
|
||||
---Purpose: Converts a list of connecting Bezier Curves 2d to a
|
||||
-- BSplineCurve 2d.
|
||||
-- if possible, the continuity of the BSpline will be
|
||||
-- increased to more than C0.
|
||||
|
||||
|
||||
uses
|
||||
SequenceOfReal from TColStd,
|
||||
SequenceOfInteger from TColStd,
|
||||
Array1OfReal from TColStd,
|
||||
Array1OfInteger from TColStd,
|
||||
Array1OfPnt2d from TColgp,
|
||||
SequenceOfPnt2d from TColgp,
|
||||
SequenceOfArray1OfPoles2d from Convert
|
||||
|
||||
|
||||
raises
|
||||
ConstructionError from Standard
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
--- Don't forget to use the method Perform before accessing the Result.
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
is
|
||||
Create( AngularTolerance : Real = 1.0e-4 )
|
||||
returns CompBezierCurves2dToBSplineCurve2d from ShapeConstruct;
|
||||
|
||||
AddCurve( me : in out;
|
||||
Poles : Array1OfPnt2d from TColgp)
|
||||
is static;
|
||||
|
||||
|
||||
Perform(me: in out)
|
||||
---Purpose: Computes the algorithm.
|
||||
is static;
|
||||
|
||||
|
||||
Degree(me) returns Integer from Standard
|
||||
is static;
|
||||
|
||||
NbPoles(me) returns Integer from Standard
|
||||
is static;
|
||||
|
||||
Poles(me; Poles : in out Array1OfPnt2d from TColgp)
|
||||
is static;
|
||||
|
||||
NbKnots(me) returns Integer from Standard
|
||||
is static;
|
||||
|
||||
KnotsAndMults(me;
|
||||
Knots : in out Array1OfReal from TColStd;
|
||||
Mults : in out Array1OfInteger from TColStd)
|
||||
is static;
|
||||
|
||||
|
||||
fields
|
||||
mySequence : SequenceOfArray1OfPoles2d from Convert;
|
||||
CurvePoles : SequenceOfPnt2d from TColgp;
|
||||
CurveKnots : SequenceOfReal from TColStd;
|
||||
KnotsMultiplicities : SequenceOfInteger from TColStd;
|
||||
myDegree : Integer from Standard;
|
||||
myAngular : Real from Standard;
|
||||
myDone : Boolean from Standard;
|
||||
|
||||
end CompBezierCurves2dToBSplineCurve2d;
|
244
src/ShapeConstruct/ShapeConstruct_CompBezierCurves2dToBSplineCurve2d.cxx
Executable file
244
src/ShapeConstruct/ShapeConstruct_CompBezierCurves2dToBSplineCurve2d.cxx
Executable file
@@ -0,0 +1,244 @@
|
||||
// File: ShapeConstruct_CompBezierCurves2dToBSplineCurve2d.cxx
|
||||
// Created: Wed Oct 20 14:55:08 1993
|
||||
// Author: Bruno DUMORTIER
|
||||
// <dub@topsn3>
|
||||
// modified 25/06/1996 PMN : Ajout d'une tolerance Angulaire dans le
|
||||
// constructeur pour le test de continuite G1 (1 Radians c'etait trop
|
||||
// cf BUG PRO4481)
|
||||
//rln 20.06.99 work-around
|
||||
|
||||
#include <ShapeConstruct_CompBezierCurves2dToBSplineCurve2d.ixx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
#include <BSplCLib.hxx>
|
||||
#include <PLib.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <TColgp_HArray1OfPnt2d.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeConstruct_CompBezierCurves2dToBSplineCurve2d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::
|
||||
ShapeConstruct_CompBezierCurves2dToBSplineCurve2d(
|
||||
const Standard_Real AngularTolerance) :
|
||||
myAngular(AngularTolerance),
|
||||
myDone(Standard_False)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : AddCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::AddCurve
|
||||
(const TColgp_Array1OfPnt2d& Poles)
|
||||
{
|
||||
if ( !mySequence.IsEmpty()) {
|
||||
gp_Pnt2d P1,P2;
|
||||
P1 = mySequence.Last()->Value(mySequence.Last()->Upper());
|
||||
P2 = Poles(Poles.Lower());
|
||||
|
||||
// User defined tolerance NYI
|
||||
// Standard_ConstructionError_Raise_if
|
||||
// ( !P1.IsEqual(P2,Precision::Confusion()),
|
||||
// "ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::Addcurve");
|
||||
|
||||
}
|
||||
myDone = Standard_False;
|
||||
Handle(TColgp_HArray1OfPnt2d) HPoles =
|
||||
new TColgp_HArray1OfPnt2d(Poles.Lower(),Poles.Upper());
|
||||
HPoles->ChangeArray1() = Poles;
|
||||
mySequence.Append(HPoles);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Degree
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::Degree()
|
||||
const {
|
||||
return myDegree;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : NbPoles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::NbPoles()
|
||||
const {
|
||||
return CurvePoles.Length();
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Poles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::Poles
|
||||
(TColgp_Array1OfPnt2d& Poles) const
|
||||
{
|
||||
Standard_Integer i, Lower = Poles.Lower(), Upper = Poles.Upper();
|
||||
Standard_Integer k = 1;
|
||||
for (i = Lower; i <= Upper; i++) {
|
||||
Poles(i) = CurvePoles(k++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : NbKnots
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::NbKnots()
|
||||
const {
|
||||
return CurveKnots.Length();
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : KnotsAndMults
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::KnotsAndMults
|
||||
(TColStd_Array1OfReal& Knots,
|
||||
TColStd_Array1OfInteger& Mults ) const
|
||||
{
|
||||
Standard_Integer i, LowerK = Knots.Lower(), UpperK = Knots.Upper();
|
||||
Standard_Integer LowerM = Mults.Lower(), UpperM = Mults.Upper();
|
||||
Standard_Integer k = 1;
|
||||
for (i = LowerK; i <= UpperK; i++) {
|
||||
Knots(i) = CurveKnots(k++);
|
||||
}
|
||||
k = 1;
|
||||
for (i = LowerM; i <= UpperM; i++) {
|
||||
Mults(i) = KnotsMultiplicities(k++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_CompBezierCurves2dToBSplineCurve2d::Perform()
|
||||
{
|
||||
myDone = Standard_True;
|
||||
CurvePoles.Clear();
|
||||
CurveKnots.Clear();
|
||||
KnotsMultiplicities.Clear();
|
||||
Standard_Integer LowerI = 1;
|
||||
Standard_Integer UpperI = mySequence.Length();
|
||||
Standard_Integer NbrCurv = UpperI-LowerI+1;
|
||||
TColStd_Array1OfReal CurveKnVals (1,NbrCurv);
|
||||
|
||||
Standard_Integer i;
|
||||
myDegree = 0;
|
||||
for ( i = 1; i <= mySequence.Length(); i++) {
|
||||
myDegree = Max( myDegree, (mySequence(i))->Length() -1);
|
||||
}
|
||||
|
||||
Standard_Real D1, D2, Lambda, Det=0.;
|
||||
gp_Pnt2d P1, P2, P3;
|
||||
Standard_Integer Deg, Inc, MaxDegree = myDegree;
|
||||
TColgp_Array1OfPnt2d Points(1, myDegree+1);
|
||||
|
||||
for (i = LowerI ; i <= UpperI ; i++) {
|
||||
// 1- Elever la courbe de Bezier au degre maximum.
|
||||
Deg = mySequence(i)->Length()-1;
|
||||
Inc = myDegree - Deg;
|
||||
if ( Inc > 0) {
|
||||
BSplCLib::IncreaseDegree(myDegree,
|
||||
mySequence(i)->Array1(), PLib::NoWeights(),
|
||||
Points, PLib::NoWeights());
|
||||
}
|
||||
else {
|
||||
Points = mySequence(i)->Array1();
|
||||
}
|
||||
|
||||
// 2- Traiter le noeud de jonction entre 2 courbes de Bezier.
|
||||
if (i == LowerI) {
|
||||
// Traitement du noeud initial de la BSpline.
|
||||
for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) {
|
||||
CurvePoles.Append(Points(j));
|
||||
}
|
||||
CurveKnVals(1) = 1.; // Pour amorcer la serie.
|
||||
KnotsMultiplicities.Append(MaxDegree+1);
|
||||
Det = 1.;
|
||||
}
|
||||
|
||||
|
||||
if (i != LowerI) {
|
||||
P2 = Points(1);
|
||||
P3 = Points(2);
|
||||
gp_Vec2d V1(P1, P2), V2(P2, P3);
|
||||
D1 = P1.SquareDistance(P2);
|
||||
D2 = P3.SquareDistance(P2);
|
||||
Lambda = Sqrt(D2/D1);
|
||||
|
||||
|
||||
// Traitement de la tangence entre la Bezier et sa precedente.
|
||||
// Ceci permet d''assurer au moins une continuite C1 si
|
||||
// les tangentes sont coherentes.
|
||||
|
||||
|
||||
// Test de l'angle a myAngular
|
||||
|
||||
if (V1.Magnitude() > gp::Resolution() &&
|
||||
V2.Magnitude() > gp::Resolution() &&
|
||||
V1.IsParallel(V2, myAngular) &&
|
||||
MaxDegree > 1) {//rln 20.06.99 work-around
|
||||
KnotsMultiplicities.Append(MaxDegree-1);
|
||||
CurveKnVals(i) = CurveKnVals(i-1) * Lambda;
|
||||
Det += CurveKnVals(i);
|
||||
|
||||
}
|
||||
else {
|
||||
CurveKnVals(i) = 1.0e0 ;
|
||||
Det += CurveKnVals(i) ;
|
||||
CurvePoles.Append(Points(1));
|
||||
KnotsMultiplicities.Append(MaxDegree);
|
||||
}
|
||||
|
||||
// Stocker les poles.
|
||||
for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) {
|
||||
CurvePoles.Append(Points(j));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (i == UpperI) {
|
||||
// Traitement du noeud terminal de la BSpline.
|
||||
CurvePoles.Append(Points(MaxDegree+1));
|
||||
KnotsMultiplicities.Append(MaxDegree+1);
|
||||
}
|
||||
P1 = Points(MaxDegree);
|
||||
}
|
||||
|
||||
// Corriger les valeurs nodales pour les faire varier dans [0.,1.].
|
||||
CurveKnots.Append(0.0);
|
||||
for (i = 2 ; i <= NbrCurv ; i++) {
|
||||
CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det));
|
||||
}
|
||||
CurveKnots.Append(1.0);
|
||||
}
|
||||
|
||||
|
72
src/ShapeConstruct/ShapeConstruct_CompBezierCurvesToBSplineCurve.cdl
Executable file
72
src/ShapeConstruct/ShapeConstruct_CompBezierCurvesToBSplineCurve.cdl
Executable file
@@ -0,0 +1,72 @@
|
||||
-- File: ShapeConstruct_CompBezierCurvesToBSplineCurve.cdl
|
||||
-- Created: Wed Oct 20 11:54:50 1993
|
||||
-- Author: Bruno DUMORTIER
|
||||
-- <dub@topsn3>
|
||||
---Copyright: Matra Datavision 1993
|
||||
|
||||
|
||||
class CompBezierCurvesToBSplineCurve from ShapeConstruct
|
||||
|
||||
---Purpose: Converts a list of connecting Bezier Curves to a
|
||||
-- BSplineCurve.
|
||||
-- if possible, the continuity of the BSpline will be
|
||||
-- increased to more than C0.
|
||||
|
||||
uses
|
||||
Array1OfReal from TColStd,
|
||||
SequenceOfReal from TColStd,
|
||||
SequenceOfInteger from TColStd,
|
||||
Array1OfInteger from TColStd,
|
||||
Array1OfPnt from TColgp,
|
||||
SequenceOfPnt from TColgp,
|
||||
SequenceOfArray1OfPoles from Convert
|
||||
|
||||
-------------------------------------------------------------------------
|
||||
--- Don't forget to use the method Perform before accessing the Result.
|
||||
-------------------------------------------------------------------------
|
||||
|
||||
raises
|
||||
ConstructionError from Standard
|
||||
|
||||
is
|
||||
Create ( AngularTolerance : Real = 1.0e-4 )
|
||||
returns CompBezierCurvesToBSplineCurve from ShapeConstruct;
|
||||
|
||||
AddCurve( me : in out;
|
||||
Poles : Array1OfPnt from TColgp)
|
||||
is static;
|
||||
|
||||
|
||||
Perform(me: in out)
|
||||
---Purpose: Computes the algorithm.
|
||||
is static;
|
||||
|
||||
|
||||
Degree(me) returns Integer from Standard
|
||||
is static;
|
||||
|
||||
NbPoles(me) returns Integer from Standard
|
||||
is static;
|
||||
|
||||
Poles(me; Poles : in out Array1OfPnt from TColgp)
|
||||
is static;
|
||||
|
||||
NbKnots(me) returns Integer from Standard
|
||||
is static;
|
||||
|
||||
KnotsAndMults(me;
|
||||
Knots : in out Array1OfReal from TColStd;
|
||||
Mults : in out Array1OfInteger from TColStd)
|
||||
is static;
|
||||
|
||||
|
||||
fields
|
||||
mySequence : SequenceOfArray1OfPoles from Convert;
|
||||
CurvePoles : SequenceOfPnt from TColgp;
|
||||
CurveKnots : SequenceOfReal from TColStd;
|
||||
KnotsMultiplicities : SequenceOfInteger from TColStd;
|
||||
myDegree : Integer from Standard;
|
||||
myAngular : Real from Standard;
|
||||
myDone : Boolean from Standard;
|
||||
|
||||
end CompBezierCurvesToBSplineCurve;
|
241
src/ShapeConstruct/ShapeConstruct_CompBezierCurvesToBSplineCurve.cxx
Executable file
241
src/ShapeConstruct/ShapeConstruct_CompBezierCurvesToBSplineCurve.cxx
Executable file
@@ -0,0 +1,241 @@
|
||||
// File: ShapeConstruct_CompBezierCurvesToBSplineCurve.cxx
|
||||
// Created: Wed Oct 20 14:55:08 1993
|
||||
// Author: Bruno DUMORTIER
|
||||
// <dub@topsn3>
|
||||
// modified 25/06/1996 PMN : Ajout d'une tolerance Angulaire dans le
|
||||
// constructeur pour le test de continuite G1 (1 Radians c'etait trop
|
||||
// cf BUG PRO4481)
|
||||
//rln 20.06.99 work-around
|
||||
|
||||
#include <ShapeConstruct_CompBezierCurvesToBSplineCurve.ixx>
|
||||
|
||||
#include <Precision.hxx>
|
||||
#include <BSplCLib.hxx>
|
||||
#include <PLib.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <TColgp_HArray1OfPnt.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeConstruct_CompBezierCurvesToBSplineCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
|
||||
ShapeConstruct_CompBezierCurvesToBSplineCurve::
|
||||
ShapeConstruct_CompBezierCurvesToBSplineCurve(
|
||||
const Standard_Real AngularTolerance) :
|
||||
myAngular(AngularTolerance),
|
||||
myDone(Standard_False)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : AddCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_CompBezierCurvesToBSplineCurve::AddCurve
|
||||
(const TColgp_Array1OfPnt& Poles)
|
||||
{
|
||||
if ( !mySequence.IsEmpty()) {
|
||||
gp_Pnt P1,P2;
|
||||
P1 = mySequence.Last()->Value(mySequence.Last()->Upper());
|
||||
P2 = Poles(Poles.Lower());
|
||||
|
||||
// NYI
|
||||
// Standard_ConstructionError_Raise_if
|
||||
// ( !P1.IsEqual(P2,Precision::Confusion()),
|
||||
// "ShapeConstruct_CompBezierCurvesToBSplineCurve::Addcurve");
|
||||
}
|
||||
myDone = Standard_False;
|
||||
Handle(TColgp_HArray1OfPnt) HPoles =
|
||||
new TColgp_HArray1OfPnt(Poles.Lower(),Poles.Upper());
|
||||
HPoles->ChangeArray1() = Poles;
|
||||
mySequence.Append(HPoles);
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Degree
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer ShapeConstruct_CompBezierCurvesToBSplineCurve::Degree() const
|
||||
{
|
||||
return myDegree;
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : NbPoles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer ShapeConstruct_CompBezierCurvesToBSplineCurve::NbPoles() const
|
||||
{
|
||||
return CurvePoles.Length();
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Poles
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_CompBezierCurvesToBSplineCurve::Poles
|
||||
(TColgp_Array1OfPnt& Poles) const
|
||||
{
|
||||
Standard_Integer i, Lower = Poles.Lower(), Upper = Poles.Upper();
|
||||
Standard_Integer k = 1;
|
||||
for (i = Lower; i <= Upper; i++) {
|
||||
Poles(i) = CurvePoles(k++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : NbKnots
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer ShapeConstruct_CompBezierCurvesToBSplineCurve::NbKnots() const
|
||||
{
|
||||
return CurveKnots.Length();
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : KnotsAndMults
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_CompBezierCurvesToBSplineCurve::KnotsAndMults
|
||||
(TColStd_Array1OfReal& Knots,
|
||||
TColStd_Array1OfInteger& Mults ) const
|
||||
{
|
||||
Standard_Integer i, LowerK = Knots.Lower(), UpperK = Knots.Upper();
|
||||
Standard_Integer LowerM = Mults.Lower(), UpperM = Mults.Upper();
|
||||
Standard_Integer k = 1;
|
||||
for (i = LowerK; i <= UpperK; i++) {
|
||||
Knots(i) = CurveKnots(k++);
|
||||
}
|
||||
k = 1;
|
||||
for (i = LowerM; i <= UpperM; i++) {
|
||||
Mults(i) = KnotsMultiplicities(k++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_CompBezierCurvesToBSplineCurve::Perform()
|
||||
{
|
||||
myDone = Standard_True;
|
||||
CurvePoles.Clear();
|
||||
CurveKnots.Clear();
|
||||
KnotsMultiplicities.Clear();
|
||||
Standard_Integer LowerI = 1;
|
||||
Standard_Integer UpperI = mySequence.Length();
|
||||
Standard_Integer NbrCurv = UpperI-LowerI+1;
|
||||
|
||||
TColStd_Array1OfReal CurveKnVals (1,NbrCurv);
|
||||
|
||||
Standard_Integer i;
|
||||
myDegree = 0;
|
||||
for ( i = 1; i <= mySequence.Length(); i++) {
|
||||
myDegree = Max( myDegree, (mySequence(i))->Length() -1);
|
||||
}
|
||||
|
||||
Standard_Real D1, D2, Lambda, Det=0.;
|
||||
gp_Pnt P1, P2, P3;
|
||||
Standard_Integer Deg, Inc, MaxDegree = myDegree;
|
||||
TColgp_Array1OfPnt Points(1, myDegree+1);
|
||||
|
||||
for (i = LowerI ; i <= UpperI ; i++) {
|
||||
// 1- Elever la courbe de Bezier au degre maximum.
|
||||
Deg = mySequence(i)->Length()-1;
|
||||
Inc = myDegree - Deg;
|
||||
if ( Inc > 0) {
|
||||
BSplCLib::IncreaseDegree(myDegree,
|
||||
mySequence(i)->Array1(), PLib::NoWeights(),
|
||||
Points, PLib::NoWeights());
|
||||
}
|
||||
else {
|
||||
Points = mySequence(i)->Array1();
|
||||
}
|
||||
|
||||
// 2- Traiter le noeud de jonction entre 2 courbes de Bezier.
|
||||
if (i == LowerI) {
|
||||
// Traitement du noeud initial de la BSpline.
|
||||
for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) {
|
||||
CurvePoles.Append(Points(j));
|
||||
}
|
||||
CurveKnVals(1) = 1.; // Pour amorcer la serie.
|
||||
KnotsMultiplicities.Append(MaxDegree+1);
|
||||
Det = 1.;
|
||||
}
|
||||
|
||||
|
||||
if (i != LowerI) {
|
||||
P2 = Points(1);
|
||||
P3 = Points(2);
|
||||
gp_Vec V1(P1, P2), V2(P2, P3);
|
||||
D1 = P1.SquareDistance(P2);
|
||||
D2 = P3.SquareDistance(P2);
|
||||
Lambda = Sqrt(D2/D1);
|
||||
|
||||
|
||||
// Traitement de la tangence entre la Bezier et sa precedente.
|
||||
// Ceci permet d''assurer au moins une continuite C1 si
|
||||
// les tangentes sont coherentes.
|
||||
|
||||
if (V1.Magnitude() > gp::Resolution() &&
|
||||
V2.Magnitude() > gp::Resolution() &&
|
||||
V1.IsParallel(V2, myAngular ) &&
|
||||
MaxDegree > 1) {//rln 20.06.99 work-around
|
||||
KnotsMultiplicities.Append(MaxDegree-1);
|
||||
CurveKnVals(i) = CurveKnVals(i-1) * Lambda;
|
||||
Det += CurveKnVals(i);
|
||||
|
||||
}
|
||||
else {
|
||||
CurvePoles.Append(Points(1));
|
||||
KnotsMultiplicities.Append(MaxDegree);
|
||||
CurveKnVals(i) = 1.0e0 ;
|
||||
Det += CurveKnVals(i) ;
|
||||
}
|
||||
|
||||
// Stocker les poles.
|
||||
for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) {
|
||||
CurvePoles.Append(Points(j));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (i == UpperI) {
|
||||
// Traitement du noeud terminal de la BSpline.
|
||||
CurvePoles.Append(Points(MaxDegree+1));
|
||||
KnotsMultiplicities.Append(MaxDegree+1);
|
||||
}
|
||||
P1 = Points(MaxDegree);
|
||||
}
|
||||
|
||||
// Corriger les valeurs nodales pour les faire varier dans [0.,1.].
|
||||
CurveKnots.Append(0.0);
|
||||
for (i = 2 ; i <= NbrCurv ; i++) {
|
||||
CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det));
|
||||
}
|
||||
CurveKnots.Append(1.0);
|
||||
}
|
||||
|
||||
|
88
src/ShapeConstruct/ShapeConstruct_Curve.cdl
Executable file
88
src/ShapeConstruct/ShapeConstruct_Curve.cdl
Executable file
@@ -0,0 +1,88 @@
|
||||
-- File: ShapeConstruct_Curve.cdl
|
||||
-- Created: Tue Jul 14 10:11:02 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@pronox.nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
class Curve from ShapeConstruct
|
||||
|
||||
---Purpose: Adjusts curve to have start and end points at the given
|
||||
-- points (currently works on lines and B-Splines only)
|
||||
|
||||
uses
|
||||
|
||||
Pnt from gp,
|
||||
Pnt2d from gp,
|
||||
Curve from Geom,
|
||||
Curve from Geom2d,
|
||||
BSplineCurve from Geom,
|
||||
BSplineCurve from Geom2d,
|
||||
HArray1OfReal from TColStd,
|
||||
Array1OfReal from TColStd
|
||||
|
||||
is
|
||||
|
||||
AdjustCurve (me; C3D: Curve from Geom;
|
||||
P1, P2: Pnt from gp;
|
||||
take1, take2: Boolean = Standard_True)
|
||||
returns Boolean;
|
||||
---Purpose : Modifies a curve in order to make its bounds confused with
|
||||
-- given points.
|
||||
-- Works only on lines and B-Splines, returns True in this case,
|
||||
-- else returns False.
|
||||
-- For line considers both bounding points, for B-Splines only
|
||||
-- specified.
|
||||
--
|
||||
-- Warning : Does not check if curve should be reversed
|
||||
|
||||
AdjustCurveSegment (me; C3D: Curve from Geom;
|
||||
P1, P2: Pnt from gp;
|
||||
U1, U2: Real)
|
||||
returns Boolean;
|
||||
---Purpose : Modifies a curve in order to make its bounds confused with
|
||||
-- given points.
|
||||
-- Works only on lines and B-Splines.
|
||||
--
|
||||
-- For lines works as previous method, B-Splines are segmented
|
||||
-- at the given values and then are adjusted to the points.
|
||||
|
||||
AdjustCurve2d (me; C2D: Curve from Geom2d;
|
||||
P1, P2: Pnt2d from gp;
|
||||
take1, take2: Boolean = Standard_True)
|
||||
returns Boolean;
|
||||
---Purpose : Modifies a curve in order to make its bounds confused with
|
||||
-- given points.
|
||||
-- Works only on lines and B-Splines, returns True in this case,
|
||||
-- else returns False.
|
||||
--
|
||||
-- For line considers both bounding points, for B-Splines only
|
||||
-- specified.
|
||||
--
|
||||
-- Warning : Does not check if curve should be reversed
|
||||
|
||||
ConvertToBSpline (me; C: Curve from Geom; first, last: Real; prec: Real)
|
||||
returns BSplineCurve from Geom;
|
||||
---Purpose: Converts a curve of any type (only part from first to last)
|
||||
-- to bspline. The method of conversion depends on the type
|
||||
-- of original curve:
|
||||
-- BSpline -> C.Segment(first,last)
|
||||
-- Bezier and Line -> GeomConvert::CurveToBSplineCurve(C).Segment(first,last)
|
||||
-- Conic and Other -> Approx_Curve3d(C[first,last],prec,C1,9,1000)
|
||||
|
||||
ConvertToBSpline (me; C: Curve from Geom2d; first, last: Real; prec: Real)
|
||||
returns BSplineCurve from Geom2d;
|
||||
---Purpose: Converts a curve of any type (only part from first to last)
|
||||
-- to bspline. The method of conversion depends on the type
|
||||
-- of original curve:
|
||||
-- BSpline -> C.Segment(first,last)
|
||||
-- Bezier and Line -> GeomConvert::CurveToBSplineCurve(C).Segment(first,last)
|
||||
-- Conic and Other -> Approx_Curve2d(C[first,last],prec,C1,9,1000)
|
||||
|
||||
FixKnots (myclass; knots: in out HArray1OfReal from TColStd) returns Boolean;
|
||||
FixKnots (myclass; knots: in out Array1OfReal from TColStd) returns Boolean;
|
||||
---Purpose: Fix bspline knots to ensure that there is enough
|
||||
-- gap between neighbouring values
|
||||
-- Returns True if something fixed (by shifting knot)
|
||||
|
||||
|
||||
end Curve;
|
307
src/ShapeConstruct/ShapeConstruct_Curve.cxx
Executable file
307
src/ShapeConstruct/ShapeConstruct_Curve.cxx
Executable file
@@ -0,0 +1,307 @@
|
||||
#include <ShapeConstruct_Curve.ixx>
|
||||
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_Failure.hxx>
|
||||
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Lin.hxx>
|
||||
|
||||
#include <ElCLib.hxx>
|
||||
#include <Precision.hxx>
|
||||
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Geom_TrimmedCurve.hxx>
|
||||
#include <Geom_Line.hxx>
|
||||
|
||||
#include <Geom2d_BSplineCurve.hxx>
|
||||
#include <Geom2d_BezierCurve.hxx>
|
||||
#include <Geom2d_TrimmedCurve.hxx>
|
||||
#include <Geom2d_Line.hxx>
|
||||
|
||||
#include <GeomConvert.hxx>
|
||||
#include <GeomAdaptor_HCurve.hxx>
|
||||
#include <Approx_Curve3d.hxx>
|
||||
|
||||
#include <Geom2dConvert.hxx>
|
||||
#include <Geom2dAdaptor_HCurve.hxx>
|
||||
#include <Approx_Curve2d.hxx>
|
||||
|
||||
//sln 29.12.2001 OCC90 : Method FixKnots was added
|
||||
|
||||
//=======================================================================
|
||||
//function : AdjustCurve
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeConstruct_Curve::AdjustCurve(const Handle(Geom_Curve)& C3D,const gp_Pnt& P1,const gp_Pnt& P2,const Standard_Boolean take1,const Standard_Boolean take2) const
|
||||
{
|
||||
if (!take1 && !take2) return Standard_True;
|
||||
|
||||
if (C3D->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
|
||||
Handle(Geom_BSplineCurve) BSPL = Handle(Geom_BSplineCurve)::DownCast(C3D);
|
||||
if (take1) BSPL->SetPole (1,P1);
|
||||
if (take2) BSPL->SetPole (BSPL->NbPoles(),P2);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (C3D->IsKind(STANDARD_TYPE(Geom_Line))) {
|
||||
Handle(Geom_Line) L3D = Handle(Geom_Line)::DownCast(C3D);
|
||||
// ATTENTION, P1 et P2 sont supposes tous deux pertinents ...
|
||||
gp_Vec avec (P1,P2); gp_Dir adir (avec); gp_Lin alin (P1,adir);
|
||||
Standard_Real theParam = ElCLib::Parameter(alin, L3D->Lin().Location());
|
||||
alin.SetLocation (ElCLib::Value(theParam, alin));
|
||||
L3D->SetLin (alin);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AdjustCurveSegment
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeConstruct_Curve::AdjustCurveSegment(const Handle(Geom_Curve)& C3D,const gp_Pnt& P1,const gp_Pnt& P2,const Standard_Real U1,const Standard_Real U2) const
|
||||
{
|
||||
if (C3D->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
|
||||
Handle(Geom_BSplineCurve) BSPL = Handle(Geom_BSplineCurve)::DownCast(C3D);
|
||||
// Forcer l extremite c est bien
|
||||
// Propager sur le reste, c est pas mal non plus
|
||||
if (U1 >= U2) return Standard_False;
|
||||
Standard_Real UU1 = Max (U1,BSPL->FirstParameter());
|
||||
Standard_Real UU2 = Min (U2,BSPL->LastParameter());
|
||||
BSPL->Segment (UU1,UU2);
|
||||
BSPL->SetPole (1,P1);
|
||||
BSPL->SetPole (BSPL->NbPoles(),P2);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (C3D->IsKind(STANDARD_TYPE(Geom_Line))) {
|
||||
Handle(Geom_Line) L3D = Handle(Geom_Line)::DownCast(C3D);
|
||||
// ATTENTION, P1 et P2 sont supposes tous deux pertinents ...
|
||||
// NB : on ne s aide pas de U1 et U2
|
||||
gp_Vec avec (P1,P2); gp_Dir adir (avec); gp_Lin alin (P1,adir);
|
||||
Standard_Real theParam = ElCLib::Parameter(alin, L3D->Lin().Location());
|
||||
alin.SetLocation (ElCLib::Value(theParam, alin));
|
||||
L3D->SetLin (alin);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AdjustCurve2d
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeConstruct_Curve::AdjustCurve2d(const Handle(Geom2d_Curve)& C2D,const gp_Pnt2d& P1,const gp_Pnt2d& P2,const Standard_Boolean take1,const Standard_Boolean take2) const
|
||||
{
|
||||
if (!take1 && !take2) return Standard_True;
|
||||
|
||||
if (C2D->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve))) {
|
||||
Handle(Geom2d_BSplineCurve) BSPL = Handle(Geom2d_BSplineCurve)::DownCast(C2D);
|
||||
if (take1) BSPL->SetPole (1,P1);
|
||||
if (take2) BSPL->SetPole (BSPL->NbPoles(),P2);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
if (C2D->IsKind(STANDARD_TYPE(Geom2d_Line))) {
|
||||
Handle(Geom2d_Line) L2D = Handle(Geom2d_Line)::DownCast(C2D);
|
||||
// ATTENTION, P1 et P2 sont supposes tous deux pertinents ...
|
||||
gp_Vec2d avec (P1,P2); gp_Dir2d adir (avec); gp_Lin2d alin (P1,adir);
|
||||
Standard_Real theParam = ElCLib::Parameter(alin, L2D->Lin2d().Location());
|
||||
alin.SetLocation (ElCLib::Value(theParam, alin));
|
||||
L2D->SetLin2d (alin);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ConvertToBSpline
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(Geom_BSplineCurve) ShapeConstruct_Curve::ConvertToBSpline (const Handle(Geom_Curve) &C,
|
||||
const Standard_Real first,
|
||||
const Standard_Real last,
|
||||
const Standard_Real prec) const
|
||||
{
|
||||
Handle(Geom_BSplineCurve) bspl;
|
||||
|
||||
if ( C->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) ) {
|
||||
bspl = Handle(Geom_BSplineCurve)::DownCast ( C );
|
||||
}
|
||||
else if ( C->IsKind(STANDARD_TYPE(Geom_BezierCurve)) ||
|
||||
C->IsKind(STANDARD_TYPE(Geom_Line)) ) {
|
||||
Handle(Geom_Curve) tc = new Geom_TrimmedCurve ( C, first, last );
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
bspl = GeomConvert::CurveToBSplineCurve(tc);
|
||||
}
|
||||
catch ( Standard_Failure ) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: ShapeConstruct_Curve::ConvertToBSpline(): Exception in GeomConvert: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! bspl.IsNull() ) {
|
||||
// take segment if trim and range differ
|
||||
Standard_Real fbsp = bspl->FirstParameter(), lbsp = bspl->LastParameter();
|
||||
Standard_Boolean segment = Standard_False;
|
||||
if ( first > fbsp + Precision::PConfusion() ) { fbsp = first; segment = Standard_True; }
|
||||
if ( last < lbsp - Precision::PConfusion() ) { lbsp = last; segment = Standard_True; }
|
||||
if ( ! segment ) return bspl;
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
bspl = Handle(Geom_BSplineCurve)::DownCast ( bspl->Copy() );
|
||||
bspl->Segment ( fbsp, lbsp );
|
||||
return bspl;
|
||||
}
|
||||
catch ( Standard_Failure ) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: ShapeConstruct_Curve::ConvertToBSpline(): Exception in Segment: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Approx is used for conics and when ordinary methods fail
|
||||
Handle(Geom_Curve) newc = C;
|
||||
if ( ! bspl.IsNull() ) { newc = bspl; bspl.Nullify(); }
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
Approx_Curve3d Conv ( new GeomAdaptor_HCurve(newc,first,last),
|
||||
prec, GeomAbs_C1, 9, 1000 );
|
||||
if ( Conv.IsDone() || Conv.HasResult() )
|
||||
bspl = Conv.Curve();
|
||||
}
|
||||
catch ( Standard_Failure ) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: ShapeConstruct_Curve::ConvertToBSpline(): Exception in Approx_Curve3d: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
}
|
||||
return bspl;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ConvertToBSpline
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(Geom2d_BSplineCurve) ShapeConstruct_Curve::ConvertToBSpline (const Handle(Geom2d_Curve) &C,
|
||||
const Standard_Real first,
|
||||
const Standard_Real last,
|
||||
const Standard_Real prec) const
|
||||
{
|
||||
Handle(Geom2d_BSplineCurve) bspl;
|
||||
|
||||
if ( C->IsKind(STANDARD_TYPE(Geom2d_BSplineCurve)) ) {
|
||||
bspl = Handle(Geom2d_BSplineCurve)::DownCast ( C );
|
||||
}
|
||||
else if ( C->IsKind(STANDARD_TYPE(Geom2d_BezierCurve)) ||
|
||||
C->IsKind(STANDARD_TYPE(Geom2d_Line)) ) {
|
||||
Handle(Geom2d_Curve) tc = new Geom2d_TrimmedCurve ( C, first, last );
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
bspl = Geom2dConvert::CurveToBSplineCurve(tc);
|
||||
}
|
||||
catch ( Standard_Failure ) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: ShapeConstruct_Curve::ConvertToBSpline(): Exception in Geom2dConvert: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! bspl.IsNull() ) {
|
||||
// take segment if trim and range differ
|
||||
Standard_Real fbsp = bspl->FirstParameter(), lbsp = bspl->LastParameter();
|
||||
Standard_Boolean segment = Standard_False;
|
||||
if ( first > fbsp + Precision::PConfusion() ) { fbsp = first; segment = Standard_True; }
|
||||
if ( last < lbsp - Precision::PConfusion() ) { lbsp = last; segment = Standard_True; }
|
||||
if ( ! segment ) return bspl;
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
bspl = Handle(Geom2d_BSplineCurve)::DownCast ( bspl->Copy() );
|
||||
bspl->Segment ( fbsp, lbsp );
|
||||
return bspl;
|
||||
}
|
||||
catch ( Standard_Failure ) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: ShapeConstruct_Curve::ConvertToBSpline(): Exception in Segment: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Approx is used for conics and when ordinary methods fail
|
||||
Handle(Geom2d_Curve) newc = C;
|
||||
if ( ! bspl.IsNull() ) { newc = bspl; bspl.Nullify(); }
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
Approx_Curve2d Conv ( new Geom2dAdaptor_HCurve(newc,first,last),
|
||||
first, last,
|
||||
prec, prec, GeomAbs_C1, 9, 1000 );
|
||||
if ( Conv.IsDone() || Conv.HasResult() )
|
||||
bspl = Conv.Curve();
|
||||
}
|
||||
catch ( Standard_Failure ) {
|
||||
#ifdef DEB
|
||||
cout << "Warning: ShapeConstruct_Curve::ConvertToBSpline(): Exception in Approx_Curve3d: ";
|
||||
Standard_Failure::Caught()->Print(cout); cout << endl;
|
||||
#endif
|
||||
}
|
||||
return bspl;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixKnots
|
||||
//purpose : Fix coincided knots
|
||||
//=======================================================================
|
||||
Standard_Boolean ShapeConstruct_Curve::FixKnots (Handle(TColStd_HArray1OfReal) &knots)
|
||||
{
|
||||
Standard_Boolean Fixed = Standard_False;
|
||||
Standard_Integer nbKnots = knots->Length();
|
||||
Standard_Real knotVal = knots->Value(1);
|
||||
for ( Standard_Integer i=2; i <= nbKnots; i++ ) {
|
||||
Standard_Real knotNext = knots->Value(i);
|
||||
if ( knotNext - knotVal <= Epsilon(knotVal) ) {
|
||||
knotNext = knotVal + 2. * Epsilon(knotVal);
|
||||
knots->SetValue ( i, knotNext );
|
||||
Fixed = Standard_True;
|
||||
}
|
||||
knotVal = knotNext;
|
||||
}
|
||||
return Fixed;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : FixKnots
|
||||
//purpose : Fix coincided knots
|
||||
//=======================================================================
|
||||
Standard_Boolean ShapeConstruct_Curve::FixKnots (TColStd_Array1OfReal& knots)
|
||||
{
|
||||
Standard_Boolean Fixed = Standard_False;
|
||||
Standard_Integer nbKnots = knots.Length();
|
||||
Standard_Real knotVal = knots.Value(1);
|
||||
for ( Standard_Integer i=2; i <= nbKnots; i++ ) {
|
||||
Standard_Real knotNext = knots.Value(i);
|
||||
if ( knotNext - knotVal <= Epsilon(knotVal) ) {
|
||||
knotNext = knotVal + 2. * Epsilon(knotVal);
|
||||
knots.SetValue ( i, knotNext );
|
||||
Fixed = Standard_True;
|
||||
}
|
||||
knotVal = knotNext;
|
||||
}
|
||||
return Fixed;
|
||||
}
|
||||
|
38
src/ShapeConstruct/ShapeConstruct_MakeTriangulation.cdl
Executable file
38
src/ShapeConstruct/ShapeConstruct_MakeTriangulation.cdl
Executable file
@@ -0,0 +1,38 @@
|
||||
-- File: ShapeConstruct_Triangulation.cdl
|
||||
-- Created: Mon Dec 20 10:11:02 1999
|
||||
-- Author: data exchange team
|
||||
-- <det@pronox.nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
|
||||
|
||||
class MakeTriangulation from ShapeConstruct inherits MakeShape from BRepBuilderAPI
|
||||
|
||||
---Purpose:
|
||||
|
||||
uses
|
||||
|
||||
Array1OfPnt from TColgp,
|
||||
Wire from TopoDS
|
||||
|
||||
is
|
||||
|
||||
Create (pnts : Array1OfPnt from TColgp; prec : Real = 0.0)
|
||||
returns MakeTriangulation from ShapeConstruct;
|
||||
|
||||
Create (wire : Wire from TopoDS; prec : Real = 0.0)
|
||||
returns MakeTriangulation from ShapeConstruct;
|
||||
|
||||
Build (me : in out) is redefined;
|
||||
|
||||
IsDone (me) returns Boolean is redefined;
|
||||
|
||||
Triangulate (me : in out; wire : Wire from TopoDS) is private;
|
||||
|
||||
AddFacet (me : in out; wire : Wire from TopoDS) is private;
|
||||
|
||||
fields
|
||||
|
||||
myPrecision : Real from Standard;
|
||||
myWire : Wire from TopoDS;
|
||||
|
||||
end MakeTriangulation;
|
403
src/ShapeConstruct/ShapeConstruct_MakeTriangulation.cxx
Executable file
403
src/ShapeConstruct/ShapeConstruct_MakeTriangulation.cxx
Executable file
@@ -0,0 +1,403 @@
|
||||
#include <ShapeConstruct_MakeTriangulation.ixx>
|
||||
|
||||
#include <TColStd_SequenceOfInteger.hxx>
|
||||
#include <Precision.hxx>
|
||||
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <Geom_Plane.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <TColgp_HArray1OfPnt.hxx>
|
||||
#include <TColgp_SequenceOfPnt.hxx>
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Shell.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Iterator.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <TopTools_HSequenceOfShape.hxx>
|
||||
#include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <ShapeAnalysis_Edge.hxx>
|
||||
#include <ShapeAnalysis_Wire.hxx>
|
||||
#include <ShapeAnalysis_Curve.hxx>
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : IsRightContour (static)
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean IsRightContour (const TColgp_SequenceOfPnt& pts, const Standard_Real prec)
|
||||
{
|
||||
Standard_Integer len = pts.Length();
|
||||
if (len < 4) return Standard_True;
|
||||
|
||||
TColgp_Array1OfPnt thePts(1,len);
|
||||
Standard_Integer i; // svv Jan11 2000 : porting on DEC
|
||||
for (i = 1; i <= len; i++) thePts(i) = pts(i);
|
||||
|
||||
gp_XYZ Norm(0,0,0);
|
||||
if (ShapeAnalysis_Curve::IsPlanar(thePts,Norm,prec)) {
|
||||
|
||||
// Make polygonal wire from points
|
||||
BRepBuilderAPI_MakePolygon mkPoly;
|
||||
for (i = 1; i <= len; i++) mkPoly.Add(thePts(i));
|
||||
mkPoly.Close();
|
||||
mkPoly.Build();
|
||||
if (mkPoly.IsDone()) {
|
||||
|
||||
// Create mean plane
|
||||
gp_XYZ center(0,0,0);
|
||||
for (i = 1; i <= len; i++) center += thePts(i).XYZ();
|
||||
center /= len;
|
||||
gp_Pnt pc(center); gp_Dir pd(Norm); gp_Pln pl(pc,pd);
|
||||
Handle(Geom_Plane) thePlane = new Geom_Plane(pl);
|
||||
|
||||
BRep_Builder B;
|
||||
TopoDS_Face theFace;
|
||||
B.MakeFace(theFace,thePlane,Precision::Confusion());
|
||||
TopoDS_Wire theWire = mkPoly.Wire();
|
||||
B.Add(theFace,theWire);
|
||||
Handle(ShapeAnalysis_Wire) saw = new ShapeAnalysis_Wire(theWire,theFace,prec);
|
||||
return !saw->CheckSelfIntersection();
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : MeanNormal (static)
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
gp_Vec MeanNormal (const TColgp_Array1OfPnt& pts)
|
||||
{
|
||||
Standard_Integer len = pts.Length();
|
||||
if (len < 3) return gp_Vec(0,0,0);
|
||||
|
||||
Standard_Integer i;
|
||||
gp_XYZ theCenter(0,0,0);
|
||||
for (i = 1; i <= len; i++) theCenter += pts(i).XYZ();
|
||||
theCenter /= len;
|
||||
|
||||
gp_XYZ theNorm(0,0,0);
|
||||
for (i = 1; i <= len; i++) {
|
||||
gp_Vec v1(pts(i).XYZ() - theCenter);
|
||||
gp_Vec v2(pts((i==len)? 1 : i+1).XYZ() - theCenter);
|
||||
theNorm += (v1^v2).XYZ();
|
||||
}
|
||||
|
||||
return gp_Vec(theNorm).Normalized();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeConstruct_MakeTriangulation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeConstruct_MakeTriangulation::ShapeConstruct_MakeTriangulation (const TColgp_Array1OfPnt& pnts,
|
||||
const Standard_Real prec)
|
||||
{
|
||||
myPrecision = (prec > 0.0)? prec : Precision::Confusion();
|
||||
// Make polygonal wire from points
|
||||
BRepBuilderAPI_MakePolygon mkPoly;
|
||||
for (Standard_Integer i = pnts.Lower(); i <= pnts.Upper(); i++) mkPoly.Add(pnts(i));
|
||||
mkPoly.Close();
|
||||
mkPoly.Build();
|
||||
if (mkPoly.IsDone()) {
|
||||
myWire = mkPoly.Wire();
|
||||
Build();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeConstruct_MakeTriangulation
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
ShapeConstruct_MakeTriangulation::ShapeConstruct_MakeTriangulation (const TopoDS_Wire& wire,
|
||||
const Standard_Real prec)
|
||||
{
|
||||
myPrecision = (prec > 0.0)? prec : Precision::Confusion();
|
||||
myWire = wire;
|
||||
Build();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Build
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_MakeTriangulation::Build()
|
||||
{
|
||||
if (myShape.IsNull()) {
|
||||
// Triangulate polygonal wire
|
||||
if (!myWire.IsNull()) Triangulate(myWire);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsDone
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean ShapeConstruct_MakeTriangulation::IsDone() const
|
||||
{
|
||||
return (!myShape.IsNull());
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Triangulate
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_MakeTriangulation::Triangulate (const TopoDS_Wire& wire)
|
||||
{
|
||||
// Fill sequence of edges
|
||||
Handle(TopTools_HSequenceOfShape) theEdges = new TopTools_HSequenceOfShape;
|
||||
for (TopoDS_Iterator ite(wire); ite.More(); ite.Next()) theEdges->Append(ite.Value());
|
||||
Standard_Integer NbEdges = theEdges->Length();
|
||||
|
||||
if (NbEdges < 4) AddFacet(wire);
|
||||
else {
|
||||
|
||||
// Fill array of end points
|
||||
ShapeAnalysis_Edge sae;
|
||||
Handle(TColgp_HArray1OfPnt) theAPnt = new TColgp_HArray1OfPnt(1,NbEdges);
|
||||
for (Standard_Integer i = 1; i <= NbEdges; i++)
|
||||
theAPnt->SetValue(i,BRep_Tool::Pnt(sae.FirstVertex(TopoDS::Edge(theEdges->Value(i)))));
|
||||
|
||||
TopoDS_Wire theNewWire;
|
||||
|
||||
// Check planarity on array of points
|
||||
gp_XYZ Norm(0,0,0);
|
||||
if (ShapeAnalysis_Curve::IsPlanar(theAPnt->Array1(),Norm,myPrecision)) AddFacet(wire);
|
||||
else {
|
||||
|
||||
// Current contour is not planar - triangulate
|
||||
TColStd_SequenceOfInteger theSegments;
|
||||
Standard_Integer cindex = 1, seqFlag = 1;
|
||||
TColStd_Array1OfInteger llimits(1,2), rlimits(1,2);
|
||||
llimits.Init(NbEdges+1); rlimits.Init(0);
|
||||
|
||||
// Find all "good" planar segments
|
||||
while (seqFlag) {
|
||||
|
||||
// Set up limits for current sequence
|
||||
Standard_Integer llimit = llimits(seqFlag);
|
||||
Standard_Integer rlimit = rlimits(seqFlag);
|
||||
if (rlimit <= llimit) rlimit += NbEdges;
|
||||
|
||||
// Check stop condition
|
||||
if ((rlimit - llimit) > (NbEdges - 2)) break;
|
||||
|
||||
TColgp_SequenceOfPnt theSPnt;
|
||||
|
||||
// Add 3 points of minimal facet
|
||||
Standard_Integer lindex = (cindex==1? NbEdges : cindex-1);
|
||||
Standard_Integer rindex = (cindex==NbEdges? 1 : cindex+1);
|
||||
theSPnt.Append(theAPnt->Value(lindex));
|
||||
theSPnt.Append(theAPnt->Value(cindex));
|
||||
theSPnt.Append(theAPnt->Value(rindex));
|
||||
|
||||
// Try prepending points
|
||||
Standard_Boolean isGood = Standard_True;
|
||||
while (isGood) {
|
||||
cindex = (lindex==1? NbEdges : lindex-1);
|
||||
if (cindex == rindex) { AddFacet(wire); return; }
|
||||
Standard_Integer cid = cindex;
|
||||
if (rlimit > NbEdges && cid <= llimit) cid += NbEdges;
|
||||
if (cid > llimit && cid < rlimit) isGood = Standard_False;
|
||||
if (isGood) {
|
||||
theSPnt.Prepend(theAPnt->Value(cindex));
|
||||
isGood = IsRightContour(theSPnt,myPrecision);
|
||||
if (isGood) lindex = cindex;
|
||||
else theSPnt.Remove(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Try appending points
|
||||
isGood = Standard_True;
|
||||
while (isGood) {
|
||||
cindex = (rindex==NbEdges? 1 : rindex+1);
|
||||
if (cindex == lindex) { AddFacet(wire); return; }
|
||||
Standard_Integer cid = cindex;
|
||||
if (rlimit > NbEdges && cid <= llimit) cid += NbEdges;
|
||||
if (cid > llimit && cid < rlimit) isGood = Standard_False;
|
||||
if (isGood) {
|
||||
theSPnt.Append(theAPnt->Value(cindex));
|
||||
isGood = IsRightContour(theSPnt,myPrecision);
|
||||
if (isGood) rindex = cindex;
|
||||
else theSPnt.Remove(theSPnt.Length());
|
||||
}
|
||||
}
|
||||
|
||||
// Record new planar segment
|
||||
theSegments.Append(lindex);
|
||||
theSegments.Append(rindex);
|
||||
|
||||
// Set up new limits
|
||||
cindex = rindex;
|
||||
rlimits(seqFlag) = rindex;
|
||||
if (llimit > NbEdges) llimits(seqFlag) = lindex;
|
||||
|
||||
// Set up sequence index
|
||||
seqFlag = (seqFlag == 1)? 2 : 1;
|
||||
}
|
||||
|
||||
cindex = theSegments.Length();
|
||||
if (cindex%4 == 0) {
|
||||
gp_Vec theBaseNorm = MeanNormal(theAPnt->Array1());
|
||||
// Identify sequence of matching facets
|
||||
Standard_Integer len = cindex/2, lindex, rindex, seqlen, j;
|
||||
Standard_Real theC, theC1 = 0.0, theC2 = 0.0;
|
||||
Standard_Integer ii; // svv Jan11 2000 : porting on DEC
|
||||
// skl : change "i" to "ii"
|
||||
for (ii = 0; ii < len; ii++) {
|
||||
// Compute normal collinearity for facet
|
||||
lindex = theSegments(ii*2+1);
|
||||
rindex = theSegments(ii*2+2);
|
||||
seqlen = ((rindex > lindex)? rindex - lindex + 1 : NbEdges - lindex + rindex + 1);
|
||||
TColgp_Array1OfPnt theArr(1,seqlen);
|
||||
for (j = 1; j <= seqlen; j++) {
|
||||
theArr(j) = theAPnt->Value(lindex);
|
||||
lindex++;
|
||||
if (lindex > NbEdges) lindex = 1;
|
||||
}
|
||||
theC = theBaseNorm*MeanNormal(theArr);
|
||||
if (ii%2) theC2 += theC; else theC1 += theC;
|
||||
}
|
||||
Standard_Integer best1 = ((theC1 > theC2)? 0 : 2);
|
||||
|
||||
// Add "best" planar facets
|
||||
BRep_Builder B;
|
||||
TopoDS_Wire theFacetWire;
|
||||
TopoDS_Edge theLEdge, theSLEdge;
|
||||
len = cindex/4;
|
||||
// Check for special case - 1 shared line
|
||||
Standard_Boolean special = (len == 2 &&
|
||||
theSegments(best1+1) == theSegments(4+best1+2) &&
|
||||
theSegments(best1+2) == theSegments(4+best1+1));
|
||||
Standard_Integer pindex = theSegments((len-1)*4+best1+2);
|
||||
for (ii = 0; ii < len; ii++) {
|
||||
lindex = theSegments(ii*4+best1+1);
|
||||
rindex = theSegments(ii*4+best1+2);
|
||||
if (special && !theSLEdge.IsNull()) {
|
||||
TopoDS_Shape aLocalShape = theSLEdge.Reversed();
|
||||
theLEdge = TopoDS::Edge(aLocalShape);
|
||||
// theLEdge = TopoDS::Edge(theSLEdge.Reversed());
|
||||
}
|
||||
else {
|
||||
TopoDS_Vertex v1 = sae.FirstVertex(TopoDS::Edge(theEdges->Value(lindex)));
|
||||
TopoDS_Vertex v2 = sae.FirstVertex(TopoDS::Edge(theEdges->Value(rindex)));
|
||||
v1.Orientation(TopAbs_FORWARD);
|
||||
v2.Orientation(TopAbs_REVERSED);
|
||||
theLEdge = BRepBuilderAPI_MakeEdge(v1,v2);
|
||||
theSLEdge = theLEdge;
|
||||
}
|
||||
// Create new facet wire
|
||||
B.MakeWire(theFacetWire);
|
||||
B.Add(theFacetWire,theLEdge.Reversed());
|
||||
Standard_Integer cur_edge = lindex;
|
||||
while (cur_edge != rindex) {
|
||||
TopoDS_Edge theNEdge = TopoDS::Edge(theEdges->Value(cur_edge));
|
||||
B.Add(theFacetWire,theNEdge);
|
||||
if (cur_edge == NbEdges) cur_edge = 1;
|
||||
else cur_edge++;
|
||||
}
|
||||
AddFacet(theFacetWire);
|
||||
if (!special) {
|
||||
// Add edges to the new wire
|
||||
if (theNewWire.IsNull()) B.MakeWire(theNewWire);
|
||||
cur_edge = pindex;
|
||||
while (cur_edge != lindex) {
|
||||
TopoDS_Edge theNEdge = TopoDS::Edge(theEdges->Value(cur_edge));
|
||||
B.Add(theNewWire,theNEdge);
|
||||
if (cur_edge == NbEdges) cur_edge = 1;
|
||||
else cur_edge++;
|
||||
}
|
||||
B.Add(theNewWire,theLEdge);
|
||||
pindex = rindex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear storage variables
|
||||
theEdges.Nullify();
|
||||
theAPnt.Nullify();
|
||||
|
||||
// Triangulate the rest of edges
|
||||
if (!theNewWire.IsNull()) Triangulate(theNewWire);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : AddFacet
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void ShapeConstruct_MakeTriangulation::AddFacet (const TopoDS_Wire& wire)
|
||||
{
|
||||
if (wire.IsNull()) return;
|
||||
|
||||
// Fill sequence of points
|
||||
ShapeAnalysis_Edge sae;
|
||||
TColgp_SequenceOfPnt pts;
|
||||
for (TopoDS_Iterator ite(wire); ite.More(); ite.Next())
|
||||
pts.Append(BRep_Tool::Pnt(sae.FirstVertex(TopoDS::Edge(ite.Value()))));
|
||||
Standard_Integer i, nbp = pts.Length();
|
||||
if (nbp < 3) return;
|
||||
|
||||
// Create mean plane
|
||||
Standard_Real cMod, maxMod = 0.0;
|
||||
gp_XYZ maxVec, Normal(0,0,0);
|
||||
for (i = 1; i <= nbp; i++) {
|
||||
gp_XYZ vb(pts(i).XYZ());
|
||||
gp_XYZ v1(pts(i==nbp? 1 : i+1).XYZ()-vb);
|
||||
cMod = v1.SquareModulus();
|
||||
if (cMod == 0.0) continue;
|
||||
else if (cMod > maxMod) { maxMod = cMod; maxVec = v1; }
|
||||
gp_XYZ v2(pts(i==1? nbp : i-1).XYZ()-vb);
|
||||
cMod = v2.SquareModulus();
|
||||
if (cMod == 0.0) continue;
|
||||
else if (cMod > maxMod) { maxMod = cMod; maxVec = v2; }
|
||||
Normal += gp_XYZ(v1^v2);
|
||||
}
|
||||
if (Normal.SquareModulus() == 0.0) {
|
||||
if (maxMod == 0.0)
|
||||
Normal = gp_XYZ(0,0,1);
|
||||
else if (maxVec.X() != 0.0)
|
||||
Normal = gp_XYZ(-maxVec.Y()/maxVec.X(),1,0);
|
||||
else if (maxVec.Y() != 0.0)
|
||||
Normal = gp_XYZ(0,-maxVec.Z()/maxVec.Y(),1);
|
||||
else
|
||||
Normal = gp_XYZ(1,0,0);
|
||||
}
|
||||
|
||||
gp_Pln Pln(pts(1),gp_Dir(Normal));
|
||||
Handle(Geom_Plane) thePlane = new Geom_Plane(Pln);
|
||||
|
||||
// Mean plane created - build face
|
||||
BRep_Builder B;
|
||||
TopoDS_Face theFace;
|
||||
B.MakeFace(theFace,thePlane,Precision::Confusion());
|
||||
B.Add(theFace,wire);
|
||||
|
||||
// Add new face to the shell
|
||||
if (myShape.IsNull()) myShape = theFace;
|
||||
else {
|
||||
if (myShape.ShapeType() == TopAbs_FACE) {
|
||||
TopoDS_Face firstFace = TopoDS::Face(myShape);
|
||||
TopoDS_Shell theShell;
|
||||
B.MakeShell(theShell);
|
||||
myShape = theShell;
|
||||
B.Add(myShape,firstFace);
|
||||
}
|
||||
B.Add(myShape,theFace);
|
||||
}
|
||||
}
|
216
src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cdl
Executable file
216
src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cdl
Executable file
@@ -0,0 +1,216 @@
|
||||
-- File: ShapeConstruct_ProjectCurveOnSurface.cdl
|
||||
-- Created: Tue Jul 14 10:14:07 1998
|
||||
-- Author: data exchange team
|
||||
-- <det@pronox.nnov.matra-dtv.fr>
|
||||
---Copyright: Matra Datavision 1998
|
||||
-- szv#4 S4163
|
||||
|
||||
class ProjectCurveOnSurface from ShapeConstruct inherits TShared from MMgt
|
||||
|
||||
---Purpose: This tool provides a method for computing pcurve by projecting
|
||||
-- 3d curve onto a surface.
|
||||
-- Projection is done by 23 or more points (this number is changed
|
||||
-- for B-Splines according to the following rule:
|
||||
-- the total number of the points is not less than number of spans *
|
||||
-- (degree + 1);
|
||||
-- it is increased recursively starting with 23 and is added with 22
|
||||
-- until the condition is fulfilled).
|
||||
-- Isoparametric cases (if curve corresponds to U=const or V=const on
|
||||
-- the surface) are recognized with the given precision.
|
||||
|
||||
uses
|
||||
Pnt from gp,
|
||||
Pnt2d from gp,
|
||||
Curve from Geom2d,
|
||||
Curve from Geom,
|
||||
Surface from Geom,
|
||||
Array1OfPnt from TColgp,
|
||||
HArray1OfPnt from TColgp,
|
||||
Array1OfPnt2d from TColgp,
|
||||
HArray1OfPnt2d from TColgp,
|
||||
Array1OfReal from TColStd,
|
||||
HArray1OfReal from TColStd,
|
||||
Surface from ShapeAnalysis,
|
||||
Status from ShapeExtend,
|
||||
Shape from GeomAbs
|
||||
|
||||
is
|
||||
|
||||
Create returns ProjectCurveOnSurface from ShapeConstruct;
|
||||
---Purpose: Empty constructor.
|
||||
|
||||
Init (me: mutable; surf: Surface from Geom; preci: Real) is virtual;
|
||||
---Purpose: Initializes the object with all necessary parameters,
|
||||
-- i.e. surface and precision
|
||||
|
||||
Init (me : mutable; surf: Surface from ShapeAnalysis; preci : Real) is virtual;
|
||||
---Purpose: Initializes the object with all necessary parameters,
|
||||
-- i.e. surface and precision
|
||||
|
||||
SetSurface (me: mutable; surf: Surface from Geom);
|
||||
---Purpose: Loads a surface (in the form of Geom_Surface) to project on
|
||||
|
||||
SetSurface (me : mutable; surf: Surface from ShapeAnalysis);
|
||||
---Purpose: Loads a surface (in the form of ShapeAnalysis_Surface) to project on
|
||||
|
||||
SetPrecision (me : mutable; preci : Real);
|
||||
---Purpose : Sets value for current precision
|
||||
|
||||
BuildCurveMode (me : mutable) returns Boolean;
|
||||
---Purpose : Returns (modifiable) the build-curve-3d mode, by default False
|
||||
-- If True, if the projected curve has been recomputed by
|
||||
-- interpolation, the 3d curve is also rebuild by interpolation
|
||||
---C++ : return &
|
||||
|
||||
AdjustOverDegenMode (me : mutable) returns Integer; -- szv#4:S4163:12Mar99 was Boolean
|
||||
---Purpose : Returns (modifiable) the flag specifying to which side of
|
||||
-- parametrical space adjust part of pcurve which lies on seam.
|
||||
-- This is required in very rare case when 3d curve which is
|
||||
-- to be projected goes partly along the seam on the closed
|
||||
-- surface with singularity (e.g. sphere), goes through the
|
||||
-- degenerated point and paerly lies on internal area of surface.
|
||||
--
|
||||
-- If this flag is True, the seam part of such curve will be
|
||||
-- adjusted to the left side of parametric space (on sphere U=0),
|
||||
-- else to the right side (on sphere U=2*PI)
|
||||
-- Default value is True
|
||||
---Level: Advanced
|
||||
---C++ : return &
|
||||
|
||||
Status (me; Status: Status from ShapeExtend) returns Boolean;
|
||||
---Purpose: Returns the status of last Peform
|
||||
|
||||
Perform (me: mutable; c3d : in out Curve from Geom;
|
||||
First, Last: Real;
|
||||
c2d : out Curve from Geom2d;
|
||||
continuity : Shape from GeomAbs = GeomAbs_C1;
|
||||
maxdeg : Integer = 12;
|
||||
nbinterval : Integer = -1 )
|
||||
returns Boolean is virtual;
|
||||
---Purpose: Computes the projection of 3d curve onto a surface using the
|
||||
-- standard algorithm from ProjLib. Returns False if standard
|
||||
-- projector fails or raises an exception or cuts the curve by
|
||||
-- parametrical bounds of the surface. Else, if pcurve computed
|
||||
-- successfully, returns True.
|
||||
-- The continuity, maxdeg and nbinterval are parameters of call
|
||||
-- to Approx_CurveOnSurface. If nbinterval is equal to -1
|
||||
-- (default), this value is computed depending on source 3d curve
|
||||
-- and surface.
|
||||
---Status:
|
||||
-- FAIL1 if the standard projector fails (no result)
|
||||
-- FAIL2 if the standard projector raises an exception
|
||||
-- FAIL3 if the standard projector cuts the pcurve
|
||||
-- DONE1 if pcurve was computed successfully
|
||||
|
||||
PerformByProjLib(me: mutable; c3d : in out Curve from Geom;
|
||||
First, Last: Real;
|
||||
c2d : out Curve from Geom2d;
|
||||
continuity : Shape from GeomAbs = GeomAbs_C1;
|
||||
maxdeg : Integer = 12;
|
||||
nbinterval : Integer = -1)
|
||||
returns Boolean;
|
||||
---Purpose: Computes the projection of 3d curve onto a surface using the
|
||||
-- standard algorithm from ProjLib. Returns False if standard
|
||||
-- projector fails or raises an exception or cuts the curve by
|
||||
-- parametrical bounds of the surface. Else, if pcurve computed
|
||||
-- successfully, returns True.
|
||||
-- The continuity, maxdeg and nbinterval are parameters of call
|
||||
-- to Approx_CurveOnSurface. If nbinterval is equal to -1
|
||||
-- (default), this value is computed depending on source 3d curve
|
||||
-- and surface.
|
||||
---Status:
|
||||
-- FAIL1 if the standard projector fails (no result)
|
||||
-- FAIL2 if the standard projector raises an exception
|
||||
-- FAIL3 if the standard projector cuts the pcurve
|
||||
-- DONE1 if pcurve was computed successfully
|
||||
|
||||
PerformAdvanced(me: mutable; c3d : in out Curve from Geom;
|
||||
First, Last: Real;
|
||||
c2d : out Curve from Geom2d)
|
||||
returns Boolean;
|
||||
---Purpose: Computes the projection of 3d curve onto a surface using
|
||||
-- either standard projector (method PerformByStandard()) or
|
||||
-- internal one (method Perform()). The selection is done by
|
||||
-- analyzing the surface and 3d curve and is aimed to filter
|
||||
-- the cases potentially dangerous for the standard projector.
|
||||
-- If the standard projector fails, internal one is used.
|
||||
---Status:
|
||||
-- FAIL1 if no surface loaded,
|
||||
-- FAIL2 if standard projected has failed,
|
||||
-- FAIL3 if internal projected failed
|
||||
-- DONE1 if c2d was built analytically,
|
||||
-- DONE2 if c2d was approximied by internal projector,
|
||||
-- DONE3 if c3d was rebuilt (see BuildCurveMode)
|
||||
-- DONE4 if seam part of pcurve was adjusted to one side of
|
||||
-- parametric space according to flag AdjustOverDegenMode
|
||||
-- DONE5 if c2d was computed by PerformByProjLib()
|
||||
|
||||
---Level: Private
|
||||
|
||||
ProjectAnalytic (me; c3d: Curve from Geom)
|
||||
returns Curve from Geom2d is private;
|
||||
|
||||
ApproxPCurve (me: mutable; nbrPnt : Integer;
|
||||
points : Array1OfPnt from TColgp;
|
||||
params : Array1OfReal from TColStd;
|
||||
points2d: out Array1OfPnt2d from TColgp;
|
||||
c2d : out Curve from Geom2d)
|
||||
returns Boolean is private;
|
||||
|
||||
InterpolatePCurve (me; nbrPnt : Integer;
|
||||
points2d: in out HArray1OfPnt2d from TColgp;
|
||||
params : in out HArray1OfReal from TColStd;
|
||||
orig : Curve from Geom)
|
||||
returns Curve from Geom2d is private;
|
||||
|
||||
ApproximatePCurve (me; nbrPnt : Integer;
|
||||
points2d: in out HArray1OfPnt2d from TColgp;
|
||||
params : in out HArray1OfReal from TColStd;
|
||||
orig : Curve from Geom)
|
||||
returns Curve from Geom2d is private;
|
||||
|
||||
InterpolateCurve3d (me; nbrPnt: Integer;
|
||||
points: in out HArray1OfPnt from TColgp;
|
||||
params: in out HArray1OfReal from TColStd;
|
||||
orig : Curve from Geom)
|
||||
returns Curve from Geom is private;
|
||||
|
||||
CheckPoints (me; points: in out HArray1OfPnt from TColgp;
|
||||
params: in out HArray1OfReal from TColStd;
|
||||
preci : in out Real)
|
||||
is private;
|
||||
|
||||
CheckPoints2d (me; points: in out HArray1OfPnt2d from TColgp;
|
||||
params: in out HArray1OfReal from TColStd;
|
||||
preci : in out Real)
|
||||
is private;
|
||||
|
||||
IsAnIsoparametric (me; nbrPnt : Integer;
|
||||
points : Array1OfPnt from TColgp;
|
||||
params : Array1OfReal from TColStd;
|
||||
isoTypeU : out Boolean;
|
||||
p1OnIso : out Boolean;
|
||||
valueP1 : out Pnt2d from gp;
|
||||
p2OnIso : out Boolean;
|
||||
valueP2 : out Pnt2d from gp;
|
||||
isoPar2d3d: out Boolean;
|
||||
cIso : out Curve from Geom;
|
||||
t1, t2 : out Real;
|
||||
pout : out Array1OfReal from TColStd)
|
||||
returns Boolean is private;
|
||||
|
||||
|
||||
fields
|
||||
|
||||
mySurf : Surface from ShapeAnalysis is protected;
|
||||
myPreci : Real is protected;
|
||||
myBuild : Boolean is protected;
|
||||
myStatus: Integer is protected;
|
||||
-- myAdjustOverDegen: Boolean; --//:c0 abv: cases when curve goes over sphere pole
|
||||
myAdjustOverDegen: Integer is protected; -- szv#4:S4163:12Mar99 was Boolean -- smh#14 - never used in open version
|
||||
|
||||
myNbCashe: Integer is protected;
|
||||
myCashe3d: Pnt from gp [2] is protected;
|
||||
myCashe2d: Pnt2d from gp [2] is protected;
|
||||
|
||||
end ProjectCurveOnSurface;
|
1582
src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx
Executable file
1582
src/ShapeConstruct/ShapeConstruct_ProjectCurveOnSurface.cxx
Executable file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user