1
0
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:
bugmaster
2011-03-16 07:30:28 +00:00
committed by bugmaster
parent 4903637061
commit 7fd59977df
16375 changed files with 3882564 additions and 0 deletions

View 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;

View 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;
}

View 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;

View 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);
}

View 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;

View 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);
}

View 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;

View 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;
}

View 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;

View 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);
}
}

View 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;

File diff suppressed because it is too large Load Diff