1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Preparing OCCT development branch

This commit is contained in:
bugmaster
2015-11-10 13:09:07 +03:00
parent 3b5f0ca372
commit cefb2f9ddd
61 changed files with 7252 additions and 50 deletions

View File

@@ -37,8 +37,11 @@ DATAEXCHANGEKERNEL : XSDRAW
OCAF : VISUALIZATION, OCAFKERNEL
DATAEXCHANGE : XDE, VISUALIZATION
XDE : DATAEXCHANGEKERNEL, XDEDRAW
HELIX : TestHelix
UNFOLDING : TestUnfolding
FULL : MODELING, OCAFKERNEL, VISUALIZATION
ALL : MODELING, OCAFKERNEL, DATAEXCHANGE
ALL : MODELING, OCAFKERNEL, DATAEXCHANGE, HELIX, UNFOLDING
TOPTEST : TKTopTest
DCAF : TKDCAF
@@ -49,3 +52,5 @@ TOBJ : TKTObjDRAW
DFBROWSER : TKDFBrowser
QAcommands : TKQADraw
VIS : TKIVtkDraw
TestHelix : TKHelix
TestUnfolding : TKUnfoldingTest

View File

@@ -0,0 +1,51 @@
! Description of available plugins for DRAW Test Harness
! *****************************************************************************
!
! Format of the file is compliant with the standard Open CASCADE resource files
! (see the Resource_Manager.cdl file for details).
!
! Each key defines a sequence of either further keys or a name of the dynamic
! library. Keys can be nested down to an arbitrary level. However, make sure
! there are no cyclic dependencies (internal checks are not performed).
!
! For details how to implement a DRAW plugin refer to the Test Harness User's
! Guide.
!
! To load a plugin use the following command in DRAW:
!
! Draw> pload [-PluginFileName] [[Key1] [Key2]...], where:
! <-PluginFileName> - Defines the name of a resource file.
! If this parameter is omitted then the default name DrawPlugin
! is used.
! According to the Open CASCADE resource file management rules
! the environment variable CSF_<PluginFileName>Defaults must
! be set and point to the directory storing the file. If it is
! omitted then it defaults to $CASROOT/src/DrawResources.
! [Key] - Defines the key(s) enumerating plugins to be loaded.
! If no keys are specified then the key named DEFAULT is used
! (if there is no such in the file then no plugins are loaded).
!
!
! NOTE: Make sure the DATAEXCHANGE or XDE key succeeds the OCAF key in a sequence
!
DEFAULT : MODELING
MODELING : TOPTEST
VISUALIZATION : AISV
OCAFKERNEL : DCAF
DATAEXCHANGEKERNEL : XSDRAW
OCAF : VISUALIZATION, OCAFKERNEL
DATAEXCHANGE : XDE, VISUALIZATION
XDE : DATAEXCHANGEKERNEL, XDEDRAW
FULL : MODELING, OCAFKERNEL, VISUALIZATION
ALL : MODELING, OCAFKERNEL, DATAEXCHANGE
TOPTEST : TKTopTest
DCAF : TKDCAF
AISV : TKViewerTest
XSDRAW : TKXSDRAW
XDEDRAW : TKXDEDRAW
TOBJ : TKTObjDRAW
DFBROWSER : TKDFBrowser
QAcommands : TKQADraw
VIS : TKIVtkDraw

View File

@@ -0,0 +1,21 @@
-- File: HelixBRep.cdl
package HelixBRep
---Purpose:
uses
gp,
TopoDS,
GeomAbs,
TColStd,
TopTools,
HelixGeom
is
class BuilderHelix;
end HelixBRep;

View File

@@ -0,0 +1,145 @@
-- File: HelixBRep_BuilderHelix.cdl
class BuilderHelix from HelixBRep
---Purpose: Implementation of building helix wire
-- Values of Error Status returned by algo:
-- 0 - OK
-- 1 - object is just initialized, it means that no input parameters were set
-- 2 - approximation fails
--
-- 10 - R < tolerance - starting point is too close to axis
-- 11 - step (Pitch) < tolerancee
-- 12 - Height < tolerance
-- 13 - TaperAngle < 0 or TaperAngle > Pi/2 - TolAng
-- Warning Status:
-- 0 - OK
-- 1 - tolerance reached by approximation > requested tolerance.
uses
Ax1 from gp,
Ax3 from gp,
Pnt from gp,
Array1OfReal from TColStd,
HArray1OfReal from TColStd,
Array1OfBoolean from TColStd,
HArray1OfBoolean from TColStd,
Shape from GeomAbs,
Shape from TopoDS,
Wire from TopoDS,
Edge from TopoDS,
ListOfShape from TopTools
is
Create
---Purpose: Empty constructor
returns BuilderHelix from HelixBRep;
---C++: alias "Standard_EXPORT virtual ~HelixBRep_BuilderHelix();"
SetParameters(me:out; theAxis: Ax3 from gp;
theDiams: Array1OfReal from TColStd;
theHeights: Array1OfReal from TColStd ;
thePitches: Array1OfReal from TColStd ;
theIsPitches: Array1OfBoolean from TColStd);
---Purpose: Sets parameters of general composite helix
SetParameters(me:out; theAxis: Ax3 from gp;
theDiam: Real from Standard;
theHeights: Array1OfReal from TColStd ;
thePitches: Array1OfReal from TColStd ;
theIsPitches: Array1OfBoolean from TColStd);
---Purpose: Sets parameters of pure helix
SetParameters(me:out; theAxis: Ax3 from gp;
theDiam1: Real from Standard;
theDiam2: Real from Standard;
theHeights: Array1OfReal from TColStd ;
thePitches: Array1OfReal from TColStd ;
theIsPitches: Array1OfBoolean from TColStd);
---Purpose: Sets parameters of pure spiral
SetParameters(me:out; theAxis: Ax3 from gp;
theDiams: Array1OfReal from TColStd;
thePitches: Array1OfReal from TColStd ;
theNbTurns: Array1OfReal from TColStd);
---Purpose: Sets parameters of general composite helix
SetParameters(me:out; theAxis: Ax3 from gp;
theDiam: Real from Standard;
thePitches: Array1OfReal from TColStd ;
theNbTurns: Array1OfReal from TColStd);
---Purpose: Sets parameters of pure helix
SetParameters(me:out; theAxis: Ax3 from gp;
theDiam1: Real from Standard;
theDiam2: Real from Standard;
thePitches: Array1OfReal from TColStd ;
theNbTurns: Array1OfReal from TColStd);
---Purpose: Sets parameters of pure spiral
SetApproxParameters(me:out; theTolerance: Real from Standard;
theMaxDegree: Integer from Standard;
theContinuity: Shape from GeomAbs);
---Purpose: Sets parameters for approximation
Perform(me:out) ;
---Purpose: Performs calculations
ToleranceReached(me) returns Real from Standard;
---Purpose: Gets tolerance reached by approximation
ErrorStatus(me)
---Purpose: Returns error status of algorithm
returns Integer from Standard;
WarningStatus(me)
---Purpose: Returns warning status of algorithm
returns Integer from Standard;
Shape(me) returns Shape from TopoDS;
---Purpose: Gets result of algorithm
---C++: return const &
BuildPart(me:in out; theAxis: Ax1 from gp;
thePStart: Pnt from gp;
theHeight: Real from Standard;
thePitch: Real from Standard;
theTaperAngle: Real from Standard;
theIsClockwise: Boolean from Standard;
thePart: out Wire from TopoDS)
is private;
Smoothing(me: in out; theParts: in out ListOfShape from TopTools)
is private;
SmoothingEdges(me: in out; thePrev, theNext: in out Edge from TopoDS)
is private;
fields
myAxis3: Ax3 from gp is protected;
myDiams: HArray1OfReal from TColStd is protected;
myHeights: HArray1OfReal from TColStd is protected;
myPitches: HArray1OfReal from TColStd is protected;
myIsPitches: HArray1OfBoolean from TColStd is protected;
myNParts: Integer from Standard;
myTolerance: Real from Standard is protected;
myTolReached: Real from Standard is protected;
myContinuity: Shape from GeomAbs is protected;
myMaxDegree: Integer from Standard is protected;
myMaxSegments: Integer from Standard is protected;
myErrorStatus : Integer from Standard is protected;
myWarningStatus : Integer from Standard is protected;
myShape: Shape from TopoDS is protected;
end BuilderHelix;

View File

@@ -0,0 +1,630 @@
// File: HelixBRep_BuilderHelix.cxx
#include <HelixBRep_BuilderHelix.ixx>
#include <HelixGeom_BuilderHelix.hxx>
#include <TColGeom_SequenceOfCurve.hxx>
#include <Geom_Curve.hxx>
#include <BRep_Builder.hxx>
#include <TopoDS_Vertex.hxx>
#include <gp_Pnt.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
#include <gp.hxx>
#include <Precision.hxx>
#include <gp_Lin.hxx>
#include <gp_Vec.hxx>
#include <gp_Ax2.hxx>
#include <gp_Vec.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Standard_ConstructionError.hxx>
#include <TopExp.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepTools_WireExplorer.hxx>
#include <Geom_BSplineCurve.hxx>
//=======================================================================
//function :
//purpose :
//=======================================================================
HelixBRep_BuilderHelix::HelixBRep_BuilderHelix()
{
gp_Pnt aP0(0.,0.,0);
//
myAxis3.SetDirection(gp::DZ());
myAxis3.SetLocation(aP0);
myDiams = NULL;
myHeights = NULL;
myPitches = NULL;
myIsPitches = NULL;
myNParts = 1;
myShape.Nullify();
//
myTolerance=0.0001;
myContinuity=GeomAbs_C1;
myMaxDegree=8;
myMaxSegments=1000;
//
myTolReached=99.;
//
myErrorStatus = 1;
myWarningStatus = 1;
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
HelixBRep_BuilderHelix::~HelixBRep_BuilderHelix()
{
}
//=======================================================================
//function : SetParameters
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::SetParameters(const gp_Ax3& theAxis,
const TColStd_Array1OfReal& theDiams,
const TColStd_Array1OfReal& theHeights,
const TColStd_Array1OfReal& thePitches,
const TColStd_Array1OfBoolean& bIsPitches)
{
myNParts = theDiams.Length() - 1;
myAxis3 = theAxis;
myDiams = NULL;
myHeights = NULL;
myPitches = NULL;
myShape.Nullify();
myErrorStatus = 1;
myWarningStatus = 1;
if(myNParts != theHeights.Length() || myNParts != thePitches.Length() || myNParts != bIsPitches.Length()) {
Standard_ConstructionError::
Raise("HelixBRep_BuilderHelix::SetParameters: wrong array dimension");
}
myDiams = new TColStd_HArray1OfReal(1, myNParts+1);
myHeights = new TColStd_HArray1OfReal(1, myNParts);
myPitches = new TColStd_HArray1OfReal(1, myNParts);
myIsPitches = new TColStd_HArray1OfBoolean(1, myNParts);
myDiams->ChangeArray1() = theDiams;
myHeights->ChangeArray1() = theHeights;
myPitches->ChangeArray1() = thePitches;
myIsPitches->ChangeArray1() = bIsPitches;
myErrorStatus = 0;
myWarningStatus = 0;
}
//=======================================================================
//function : SetParameters
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::SetParameters(const gp_Ax3& theAxis,
const Standard_Real theDiam,
const TColStd_Array1OfReal& theHeights,
const TColStd_Array1OfReal& thePitches,
const TColStd_Array1OfBoolean& bIsPitches)
{
Standard_Integer aNbParts = theHeights.Length();
TColStd_Array1OfReal aDiams(1, aNbParts+1);
aDiams.Init(theDiam);
SetParameters(theAxis, aDiams, theHeights, thePitches, bIsPitches);
}
//=======================================================================
//function : SetParameters
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::SetParameters(const gp_Ax3& theAxis,
const Standard_Real theDiam1,
const Standard_Real theDiam2,
const TColStd_Array1OfReal& theHeights,
const TColStd_Array1OfReal& thePitches,
const TColStd_Array1OfBoolean& bIsPitches)
{
Standard_Integer aNbParts = theHeights.Length();
TColStd_Array1OfReal aDiams(1, aNbParts+1);
Standard_Integer i, j;
Standard_Real anH = 0.;
for(i = theHeights.Lower(); i <= theHeights.Upper(); ++i) {
anH += theHeights(i);
}
Standard_Real K = (theDiam2 - theDiam1)/anH;
aDiams(1) = theDiam1;
aDiams(aNbParts+1) = theDiam2;
anH = theHeights(1);
for(i = theHeights.Lower()+1, j = 2; i <= theHeights.Upper(); ++i, ++j) {
aDiams(j) = theDiam1 + K * anH;
anH += theHeights(i);
}
SetParameters(theAxis, aDiams, theHeights, thePitches, bIsPitches);
}
//=======================================================================
//function : SetApproxParameters
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::SetApproxParameters(const Standard_Real aTolerance,
const Standard_Integer aMaxDegree,
const GeomAbs_Shape aCont)
{
myTolerance=aTolerance;
myMaxDegree=aMaxDegree;
myContinuity=aCont;
}
//=======================================================================
//function : ToleranceReached
//purpose :
//=======================================================================
Standard_Real HelixBRep_BuilderHelix::ToleranceReached()const
{
return myTolReached;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::Perform()
{
if(myErrorStatus != 0) return;
Standard_Integer i;
myTolReached = 0.;
myShape.Nullify();
BRep_Builder aBB;
//aBB.MakeCompound(TopoDS::Compound(myShape));
TopTools_ListOfShape anLst;
gp_Ax1 anAxis(myAxis3.Axis());
gp_Pnt aPStart = myAxis3.Location();
aPStart.Translate(.5*myDiams->Value(1)*myAxis3.XDirection());
Standard_Boolean bIsClockwise = myAxis3.Direct();
Standard_Real aHeight;
Standard_Real aPitch;
Standard_Real aTaperAngle;
for(i = 1; i <= myNParts; ++i) {
aHeight = myHeights->Value(i);
if(myIsPitches->Value(i)) {
aPitch = myPitches->Value(i);
}
else {
aPitch = aHeight/myPitches->Value(i);
}
aTaperAngle = ATan(.5*(myDiams->Value(i+1) - myDiams->Value(i))/aHeight);
TopoDS_Wire aPart;
aBB.MakeWire(aPart);
BuildPart(anAxis, aPStart, aHeight, aPitch, aTaperAngle, bIsClockwise, aPart);
if(myErrorStatus != 0) return;
TopoDS_Vertex V1, V2;
TopExp::Vertices(aPart, V1, V2);
aPStart = BRep_Tool::Pnt(V2);
anAxis.SetLocation(anAxis.Location().Translated(aHeight*anAxis.Direction()));
anLst.Append(aPart);
//aBB.Add(myShape, aPart);
}
Smoothing(anLst);
TopTools_ListIteratorOfListOfShape anIt(anLst);
BRepBuilderAPI_MakeWire aMkWire(TopoDS::Wire(anLst.First()));
anIt.Next();
for(; anIt.More(); anIt.Next()) {
aMkWire.Add(TopoDS::Wire(anIt.Value()));
}
myShape = aMkWire.Shape();
}
//=======================================================================
//function : BuildPart
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::BuildPart(const gp_Ax1& theAxis,
const gp_Pnt& thePStart,
const Standard_Real theHeight,
const Standard_Real thePitch,
const Standard_Real theTaperAngle,
const Standard_Boolean bIsClockwise,
TopoDS_Wire& thePart)
{
if(myErrorStatus != 0) return;
myErrorStatus=0;
myWarningStatus=0;
//
// 1. check & prepare data
Standard_Real aTolPrec, aDist, aDM, aTwoPI, aC1, aT2, aT1, aT0;
//
aTolPrec=myTolerance;
Standard_Real aTolAng = 1.e-7;
//
if (theTaperAngle > M_PI/2. - aTolAng) {
myErrorStatus=13; // invalid TaperAngle value
return;
}
if (theHeight<aTolPrec) {
myErrorStatus=12; // invalid Height value
return;
}
if (thePitch<aTolPrec) {
myErrorStatus=11; // invalid Pitch value
return;
}
//
gp_Lin aLin(theAxis);
aDist=aLin.Distance(thePStart);
if (aDist<aTolPrec) {
myErrorStatus=10; // myPStart belongs to the myAxis
return;
}
aTolAng = aTolPrec/aDist;
Standard_Real aAngleStart = 0.;
Standard_Boolean bIsOutWard = Standard_False;
if(theTaperAngle > 0.) bIsOutWard = Standard_True;
//
const gp_Dir& aDir=theAxis.Direction();
gp_Vec aVec1 = gp_Vec(aDir);
gp_Pnt aM0 = theAxis.Location();
gp_Vec aVec(aM0, thePStart);
aDM=aVec1.Dot(aVec);
gp_Pnt aM1= aM0.Translated(aDM*aVec1);
gp_Vec aVecX(aM1, thePStart);
gp_Dir aDirX(aVecX);
gp_Ax2 aAx2(aM1, aDir, aDirX);
//
aTwoPI=2.*M_PI;
aC1=thePitch/aTwoPI;
aT0 = 0.;
aT1=aAngleStart;
aT2=theHeight/aC1;
//
// 2. compute
Standard_Boolean bIsDone;
Standard_Integer iErr, aNbC, i;
HelixGeom_BuilderHelix aBH;
gp_Pnt aP1, aP2;
BRep_Builder aBB;
BRepBuilderAPI_MakeEdge aBME;
TopoDS_Vertex aV1, aV2;
//TopoDS_Wire aW;
TopoDS_Edge aE;
//
aBH.SetPosition(aAx2);
aBH.SetCurveParameters(aT0, aT2, thePitch, aDist, theTaperAngle, bIsClockwise);
aBH.SetTolerance(myTolerance);
aBH.SetApproxParameters(myContinuity, myMaxDegree, myMaxSegments);
//
aBH.Perform();
iErr=aBH.ErrorStatus();
if (iErr) {
myErrorStatus=2;
return;
}
//
aBB.MakeWire(thePart);
//
myTolReached=Max(myTolReached, aBH.ToleranceReached());
TColGeom_SequenceOfCurve aSC;
aSC.Assign(aBH.Curves());
if(aT1 < 0.) {
HelixGeom_BuilderHelix aBH1;
aBH1.SetPosition(aAx2);
aBH1.SetCurveParameters(aT1, aT0, thePitch, aDist, theTaperAngle, bIsClockwise);
aBH1.SetTolerance(myTolerance);
aBH1.SetApproxParameters(myContinuity, myMaxDegree, myMaxSegments);
//
aBH1.Perform();
iErr=aBH1.ErrorStatus();
if (iErr) {
myErrorStatus=2;
return;
}
myTolReached = Max(myTolReached, aBH1.ToleranceReached());
const TColGeom_SequenceOfCurve& aSC1=aBH1.Curves();
Standard_Integer nbc = aSC1.Length();
for(i = nbc; i >= 1; i--) {
aSC.Prepend(aSC1.Value(i));
}
}
aNbC=aSC.Length();
for (i=1; i<=aNbC; ++i) {
Handle(Geom_Curve) aC=aSC(i);
//
if (i==1) {
if(aT1 > 0.) {
aT2=aC->LastParameter();
Handle(Geom_TrimmedCurve) aCT = new Geom_TrimmedCurve(aC, aT1, aT2);
aC = aCT;
}
aT1=aC->FirstParameter();
aC->D0(aT1, aP1);
aBB.MakeVertex(aV1, aP1, myTolReached);
aV1.Orientation(TopAbs_FORWARD);
}
//
aT2=aC->LastParameter();
aC->D0(aT2, aP2);
aBB.MakeVertex(aV2, aP2, myTolReached);
aV2.Orientation(TopAbs_REVERSED);
//
aBME.Init(aC, aV1, aV2);
bIsDone=aBME.IsDone();
if (!bIsDone) {
myErrorStatus=3;
return;
}
aE=aBME.Edge();
aBB.UpdateEdge(aE, myTolReached);
aBB.Add(thePart, aE);
//
aV1=aV2;
aV1.Orientation(TopAbs_FORWARD);
}
//
if(myTolReached > myTolerance) myWarningStatus = 1;
}
//=======================================================================
//function : Smoothing
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::Smoothing(TopTools_ListOfShape& theParts)
{
if(theParts.Extent() == 1) return;
BRepTools_WireExplorer anExpl;
TopoDS_Wire aPrevWire = TopoDS::Wire(theParts.First());
anExpl.Init(aPrevWire);
TopoDS_Edge aPrevEdge;
for(; anExpl.More(); anExpl.Next()) {
aPrevEdge = anExpl.Current();
}
TopTools_ListIteratorOfListOfShape anIter(theParts);
anIter.Next();
for(; anIter.More(); anIter.Next()) {
TopoDS_Wire aNextWire = TopoDS::Wire(anIter.Value());
anExpl.Clear();
anExpl.Init(aNextWire);
TopoDS_Edge aNextEdge = anExpl.Current();
//Smoothing curves
SmoothingEdges(aPrevEdge, aNextEdge);
for(; anExpl.More(); anExpl.Next()) {
aPrevEdge = anExpl.Current();
}
}
}
//=======================================================================
//function : Smoothing
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::SmoothingEdges(TopoDS_Edge& thePrev,
TopoDS_Edge& theNext)
{
static const Standard_Real EpsAng = 1.e-7;
BRep_Builder aBB;
Standard_Real f1, l1, f2, l2;
Handle(Geom_BSplineCurve) aCPrev =
Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(thePrev, f1, l1));
Handle(Geom_BSplineCurve) aCNext =
Handle(Geom_BSplineCurve)::DownCast(BRep_Tool::Curve(theNext, f2, l2));
gp_Pnt P1, P2;
gp_Vec V1, V2;
aCPrev->D1(l1, P1, V1);
aCNext->D1(f2, P2, V2);
if(V1.Angle(V2) < EpsAng) return;
V1 = 0.5*(V1 + V2);
V2 = V1;
Standard_Integer anErrorStatus = 1;
Standard_Integer aDegMax = Geom_BSplineCurve::MaxDegree();
Standard_Integer aDeg = aCPrev->Degree();
Standard_Integer i;
Standard_Boolean bPrevOK = Standard_False;
Standard_Boolean bNextOK = Standard_False;
aCPrev->MovePointAndTangent(l1, P1, V1, myTolerance, 1, -1, anErrorStatus);
if(anErrorStatus != 0) {
for(i = aDeg + 1; i <= aDegMax; ++i) {
aCPrev->IncreaseDegree(i);
aCPrev->MovePointAndTangent(l1, P1, V1, myTolerance, 1, -1, anErrorStatus);
if(anErrorStatus == 0) {
bPrevOK = Standard_True;
break;
}
}
}
else {
bPrevOK = Standard_True;
}
if(bPrevOK) {
aBB.UpdateEdge(thePrev, aCPrev, BRep_Tool::Tolerance(thePrev));
}
aDeg = aCNext->Degree();
aCNext->MovePointAndTangent(f2, P2, V2, myTolerance, -1, 1, anErrorStatus);
if(anErrorStatus != 0) {
for(i = aDeg + 1; i <= aDegMax; ++i) {
aCNext->IncreaseDegree(i);
aCNext->MovePointAndTangent(f2, P2, V2, myTolerance, -1, 1, anErrorStatus);
if(anErrorStatus == 0) {
bNextOK = Standard_True;
break;
}
}
}
else {
bNextOK = Standard_True;
}
if(bNextOK) {
aBB.UpdateEdge(theNext, aCNext, BRep_Tool::Tolerance(theNext));
}
}
//=======================================================================
//function : ErrorStatus
//purpose :
//=======================================================================
Standard_Integer HelixBRep_BuilderHelix::ErrorStatus()const
{
return myErrorStatus;
}
//=======================================================================
//function : WarningStatus
//purpose :
//=======================================================================
Standard_Integer HelixBRep_BuilderHelix::WarningStatus()const
{
return myWarningStatus;
}
//=======================================================================
//function : Shape
//purpose :
//=======================================================================
const TopoDS_Shape& HelixBRep_BuilderHelix::Shape() const
{
return myShape;
}
//=======================================================================
//function : SetParameters
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::SetParameters(const gp_Ax3& theAxis,
const TColStd_Array1OfReal& theDiams,
const TColStd_Array1OfReal& thePitches,
const TColStd_Array1OfReal& theNbTurns)
{
Standard_Integer aNbParts = theDiams.Length() - 1;
if(aNbParts != thePitches.Length() || aNbParts != theNbTurns.Length()) {
Standard_ConstructionError::
Raise("HelixBRep_BuilderHelix::SetParameters: wrong array dimension");
}
TColStd_Array1OfReal aHeights(1, aNbParts);
TColStd_Array1OfBoolean bIsPitches(1, aNbParts);
bIsPitches.Init(Standard_True);
Standard_Integer i, ip, in;
for(i = 1, ip = thePitches.Lower(), in = theNbTurns.Lower(); i <= thePitches.Length(); ++i, ip++, in++) {
aHeights(i) = thePitches(ip)*theNbTurns(in);
}
SetParameters(theAxis, theDiams, aHeights, thePitches, bIsPitches);
}
//=======================================================================
//function : SetParameters
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::SetParameters(const gp_Ax3& theAxis,
const Standard_Real theDiam,
const TColStd_Array1OfReal& thePitches,
const TColStd_Array1OfReal& theNbTurns)
{
Standard_Integer aNbParts = thePitches.Length();
if(aNbParts != theNbTurns.Length()) {
Standard_ConstructionError::
Raise("HelixBRep_BuilderHelix::SetParameters: wrong array dimension");
}
TColStd_Array1OfReal aHeights(1, aNbParts);
TColStd_Array1OfBoolean bIsPitches(1, aNbParts);
bIsPitches.Init(Standard_True);
Standard_Integer i, ip, in;
for(i = 1, ip = thePitches.Lower(), in = theNbTurns.Lower(); i <= thePitches.Length(); ++i, ip++, in++) {
aHeights(i) = thePitches(ip)*theNbTurns(in);
}
SetParameters(theAxis, theDiam, aHeights, thePitches, bIsPitches);
}
//=======================================================================
//function : SetParameters
//purpose :
//=======================================================================
void HelixBRep_BuilderHelix::SetParameters(const gp_Ax3& theAxis,
const Standard_Real theDiam1,
const Standard_Real theDiam2,
const TColStd_Array1OfReal& thePitches,
const TColStd_Array1OfReal& theNbTurns)
{
Standard_Integer aNbParts = thePitches.Length();
if(aNbParts != theNbTurns.Length()) {
Standard_ConstructionError::
Raise("HelixBRep_BuilderHelix::SetParameters: wrong array dimension");
}
TColStd_Array1OfReal aHeights(1, aNbParts);
TColStd_Array1OfBoolean bIsPitches(1, aNbParts);
bIsPitches.Init(Standard_True);
Standard_Integer i, ip, in;
for(i = 1, ip = thePitches.Lower(), in = theNbTurns.Lower(); i <= thePitches.Length(); ++i, ip++, in++) {
aHeights(i) = thePitches(ip)*theNbTurns(in);
}
SetParameters(theAxis, theDiam1, theDiam2, aHeights, thePitches, bIsPitches);
}

View File

@@ -0,0 +1,35 @@
-- File: HelixGeom.cdl
package HelixGeom
---Purpose:
uses
MMgt,
gp,
TColStd,
GeomAbs,
Geom,
TColGeom,
GeomAdaptor,
Adaptor3d,
GeomFill
is
deferred class BuilderApproxCurve;
deferred class BuilderHelixGen;
class HelixCurve;
class HHelixCurve;
class BuilderHelixCoil;
class BuilderHelix;
class Tools;
--
private class GHHelixCurve instantiates GenHCurve from Adaptor3d
(HelixCurve from HelixGeom);
end HelixGeom;

View File

@@ -0,0 +1,72 @@
-- File: HelixGeom_BuilderApproxCurve.cdl
deferred class BuilderApproxCurve from HelixGeom
---Purpose: Root class for algorithm of building helix curves
uses
Shape from GeomAbs,
SequenceOfCurve from TColGeom
--raises
is
Initialize
---Purpose: Sets default values of aprroximation parameters
returns BuilderApproxCurve from HelixGeom;
---C++: alias "Standard_EXPORT virtual ~HelixGeom_BuilderApproxCurve();"
SetApproxParameters(me:out;
aCont : Shape from GeomAbs;
aMaxDegree: Integer from Standard;
aMaxSeg : Integer from Standard);
---Purpose: Sets aprroximation parameters
ApproxParameters(me;
aCont :out Shape from GeomAbs;
aMaxDegree:out Integer from Standard;
aMaxSeg :out Integer from Standard);
---Purpose: Gets aprroximation parameters
SetTolerance(me:out;
aTolerance: Real from Standard);
---Purpose: Sets aprroximation tolerance
Tolerance(me)
returns Real from Standard;
---Purpose: Gets aprroximation tolerance
ToleranceReached(me)
---Purpose: Gets actual tolerance reached by approximation algorithm
returns Real from Standard;
Curves(me)
---Purpose: Gets sequence of Bspline curves representing helix coins.
returns SequenceOfCurve from TColGeom;
---C++: return const &
ErrorStatus(me)
---Purpose: Returns error status of algorithm
returns Integer from Standard;
WarningStatus(me)
---Purpose: Returns warning status of algorithm
returns Integer from Standard;
Perform(me:out)
---Purpose: Performs calculations.
-- Must be redefined.
is deferred;
fields
myErrorStatus : Integer from Standard is protected;
myWarningStatus : Integer from Standard is protected;
myTolerance : Real from Standard is protected;
myCont : Shape from GeomAbs is protected;
myMaxDegree : Integer from Standard is protected;
myMaxSeg : Integer from Standard is protected;
--
myTolReached : Real from Standard is protected;
myCurves : SequenceOfCurve from TColGeom is protected;
end BuilderApproxCurve;

View File

@@ -0,0 +1,100 @@
// File: HelixGeom_BuilderApproxCurve.cxx
#include <HelixGeom_BuilderApproxCurve.ixx>
//=======================================================================
//function :
//purpose :
//=======================================================================
HelixGeom_BuilderApproxCurve::HelixGeom_BuilderApproxCurve()
{
myTolerance=0.0001;
myCont=GeomAbs_C2;
myMaxDegree=8;
myMaxSeg=150;
//
myTolReached=99.;
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
HelixGeom_BuilderApproxCurve::~HelixGeom_BuilderApproxCurve()
{
}
//=======================================================================
//function : SetApproxParameters
//purpose :
//=======================================================================
void HelixGeom_BuilderApproxCurve::SetApproxParameters(const GeomAbs_Shape aCont,
const Standard_Integer aMaxDegree,
const Standard_Integer aMaxSeg)
{
myCont=aCont;
myMaxDegree=aMaxDegree;
myMaxSeg=aMaxSeg;
}
//=======================================================================
//function : ApproxParameters
//purpose :
//=======================================================================
void HelixGeom_BuilderApproxCurve::ApproxParameters(GeomAbs_Shape& aCont,
Standard_Integer& aMaxDegree,
Standard_Integer& aMaxSeg)const
{
aCont=myCont;
aMaxDegree=myMaxDegree;
aMaxSeg=myMaxSeg;
}
//=======================================================================
//function : SetTolerance
//purpose :
//=======================================================================
void HelixGeom_BuilderApproxCurve::SetTolerance(const Standard_Real aTolerance)
{
myTolerance=aTolerance;
}
//=======================================================================
//function : Tolerance
//purpose :
//=======================================================================
Standard_Real HelixGeom_BuilderApproxCurve::Tolerance()const
{
return myTolerance;
}
//=======================================================================
//function : ToleranceReached
//purpose :
//=======================================================================
Standard_Real HelixGeom_BuilderApproxCurve::ToleranceReached()const
{
return myTolReached;
}
//=======================================================================
//function : Curves
//purpose :
//=======================================================================
const TColGeom_SequenceOfCurve& HelixGeom_BuilderApproxCurve::Curves()const
{
return myCurves;
}
//=======================================================================
//function : ErrorStatus
//purpose :
//=======================================================================
Standard_Integer HelixGeom_BuilderApproxCurve::ErrorStatus()const
{
return myErrorStatus;
}
//=======================================================================
//function : WarningStatus
//purpose :
//=======================================================================
Standard_Integer HelixGeom_BuilderApproxCurve::WarningStatus()const
{
return myWarningStatus;
}

View File

@@ -0,0 +1,38 @@
-- File: HelixGeom_BuilderHelix.cdl
class BuilderHelix from HelixGeom
inherits BuilderHelixGen from HelixGeom
---Purpose: Upper level class for geometrical algorithm of building
-- helix curves using arbitrary axis
uses
Ax2 from gp
--raises
is
Create
---Purpose: Empty constructor
returns BuilderHelix from HelixGeom;
---C++: alias "Standard_EXPORT virtual ~HelixGeom_BuilderHelix();"
SetPosition (me:out;
---Purpose: Sets coordinate axes for helix
aAx2 : Ax2 from gp);
Position (me)
---Purpose: Gets coordinate axes for helix
returns Ax2 from gp;
---C++: return const &
Perform(me:out)
---Purpose: Performs calculations
is redefined;
fields
myPosition: Ax2 from gp is protected;
end BuilderHelix;

View File

@@ -0,0 +1,165 @@
// File: HelixGeom_BuilderHelix.cxx
#include <HelixGeom_BuilderHelix.ixx>
#include <HelixGeom_BuilderHelixCoil.hxx>
#include <Geom_Curve.hxx>
#include <gp_Trsf.hxx>
#include <gp_Ax3.hxx>
#include <TColGeom_SequenceOfCurve.hxx>
//=======================================================================
//function :
//purpose :
//=======================================================================
HelixGeom_BuilderHelix::HelixGeom_BuilderHelix()
:
HelixGeom_BuilderHelixGen()
{
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
HelixGeom_BuilderHelix::~HelixGeom_BuilderHelix()
{
}
//=======================================================================
//function : SetPosition
//purpose :
//=======================================================================
void HelixGeom_BuilderHelix::SetPosition(const gp_Ax2& aAx2)
{
myPosition=aAx2;
}
//=======================================================================
//function : Position
//purpose :
//=======================================================================
const gp_Ax2& HelixGeom_BuilderHelix::Position()const
{
return myPosition;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void HelixGeom_BuilderHelix::Perform()
{
myErrorStatus=0;
myWarningStatus=0;
//
Standard_Integer iErr, aN, i, aNbC;
Standard_Real aTwoPI, dT, aT1x, aT2x, aTR;
//HelixGeom_HelixCurve aHC;
HelixGeom_BuilderHelixCoil aBHC;
//
myCurves.Clear();
myTolReached=-1.;
aTwoPI=2.*M_PI;
//
aBHC.SetTolerance(myTolerance);
aBHC.SetApproxParameters(myCont, myMaxDegree, myMaxSeg);
//
dT=myT2-myT1;
aN=(Standard_Integer)(dT/aTwoPI);
//
if (!aN) {
aBHC.SetCurveParameters(myT1, myT2, myPitch, myRStart, myTaperAngle, myIsClockWise);
aBHC.Perform();
iErr=aBHC.ErrorStatus();
if (iErr) {
myErrorStatus=2;
return;
}
const TColGeom_SequenceOfCurve& aSC=aBHC.Curves();
const Handle(Geom_Curve)& aC=aSC(1);
myCurves.Append(aC);
myTolReached=aBHC.ToleranceReached();
}
//
else {
Standard_Boolean bIsCylindrical;
Standard_Real aTolAngle;
//
aTolAngle=1.e-4;
bIsCylindrical=fabs(myTaperAngle)<aTolAngle;
//
aT1x=myT1;
aT2x=myT1+aTwoPI;
for (i=1; i<=aN; ++i) {
//
if (i>1 && bIsCylindrical) {
Handle(Geom_Curve) aCi;
gp_Pnt aP1, aPi;
//
const Handle(Geom_Curve)& aC1=myCurves(1);
aC1->D0(aC1->FirstParameter(), aP1);
aPi.SetCoord(aP1.X(), aP1.Y(), aP1.Z()+(i-1)*myPitch);
aCi=Handle(Geom_Curve)::DownCast(aC1->Translated(aP1, aPi));
//
myCurves.Append(aCi);
//
aT1x=aT2x;
aT2x=aT1x+aTwoPI;
//
continue;
}
aBHC.SetCurveParameters(aT1x, aT2x, myPitch, myRStart, myTaperAngle, myIsClockWise);
//
aBHC.Perform();
iErr=aBHC.ErrorStatus();
if (iErr) {
myErrorStatus=2;
return;
}
//
const TColGeom_SequenceOfCurve& aSC=aBHC.Curves();
const Handle(Geom_Curve)& aC=aSC(1);
myCurves.Append(aC);
aTR=aBHC.ToleranceReached();
if(aTR>myTolReached) {
myTolReached=aTR;
}
//
aT1x=aT2x;
aT2x=aT1x+aTwoPI;
} // for (i=1; i<=aN; ++i) {
//
aT2x=myT2;
Standard_Real eps = 1.e-7*aTwoPI;
if (fabs (aT2x-aT1x)>eps) {
aBHC.SetCurveParameters(aT1x, aT2x, myPitch, myRStart, myTaperAngle, myIsClockWise);
aBHC.Perform();
iErr=aBHC.ErrorStatus();
if (iErr) {
myErrorStatus=2;
return;
}
//
const TColGeom_SequenceOfCurve& aSC=aBHC.Curves();
const Handle(Geom_Curve)& aC=aSC(1);
myCurves.Append(aC);
aTR=aBHC.ToleranceReached();
if(aTR>myTolReached) {
myTolReached=aTR;
}
}
}
//
// Transformation
gp_Trsf aTrsf;
gp_Ax3 aAx3, aAx3x(myPosition);
//
aTrsf.SetDisplacement(aAx3, aAx3x);
//
aNbC=myCurves.Length();
for (i=1; i<=aNbC; ++i) {
Handle(Geom_Curve)& aC=myCurves(i);
aC->Transform(aTrsf);
}
//
}

View File

@@ -0,0 +1,24 @@
-- File: HelixGeom_BuilderHelixCoil.cdl
class BuilderHelixCoil from HelixGeom
inherits BuilderHelixGen from HelixGeom
---Purpose: Implementation of algorithm for building helix coil with
-- axis OZ
--uses
--raises
is
Create
---Purpose: Empty constructor
returns BuilderHelixCoil from HelixGeom;
---C++: alias "Standard_EXPORT virtual ~HelixGeom_BuilderHelixCoil();"
Perform(me:out)
---Purpose: Performs calculations
is redefined;
end BuilderHelixCoil;

View File

@@ -0,0 +1,63 @@
// File: HelixGeom_BuilderHelixCoil.cxx
#include <HelixGeom_BuilderHelixCoil.ixx>
#include <HelixGeom_Tools.hxx>
#include <HelixGeom_HelixCurve.hxx>
#include <HelixGeom_HHelixCurve.hxx>
#include <Geom_BSplineCurve.hxx>
//=======================================================================
//function : HelixGeom_BuilderHelixCoil
//purpose :
//=======================================================================
HelixGeom_BuilderHelixCoil::HelixGeom_BuilderHelixCoil()
:
HelixGeom_BuilderHelixGen()
{
myT1=0.;
myT2=2.*M_PI;
myPitch=1.;
myRStart=1.;
myTaperAngle=0.;
myIsClockWise=Standard_True;
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
HelixGeom_BuilderHelixCoil::~HelixGeom_BuilderHelixCoil()
{
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void HelixGeom_BuilderHelixCoil::Perform()
{
myErrorStatus=0;
myWarningStatus=0;
//
Standard_Integer iErr;
HelixGeom_HelixCurve aAdaptor;
Handle(HelixGeom_HHelixCurve) aHAdaptor;
Handle(Geom_BSplineCurve)aBC;
//
myCurves.Clear();
//
aAdaptor.Load(myT1, myT2, myPitch, myRStart, myTaperAngle, myIsClockWise);
aHAdaptor=new HelixGeom_HHelixCurve(aAdaptor);
//
iErr=HelixGeom_Tools::ApprCurve3D(aHAdaptor,
myTolerance, myCont, myMaxSeg, myMaxDegree,
aBC, myTolReached);
if(iErr) {
myErrorStatus=2;
}
else {
myCurves.Append(aBC);
}
}

View File

@@ -0,0 +1,45 @@
-- File: HelixGeom_BuilderHelixGen.cdl
deferred class BuilderHelixGen from HelixGeom
inherits BuilderApproxCurve from HelixGeom
---Purpose: Root class for algorithms of building helix curves
--uses
--raises
is
Initialize
---Purpose: Sets default parameters
returns BuilderHelixGen from HelixGeom;
---C++: alias "Standard_EXPORT virtual ~HelixGeom_BuilderHelixGen();"
SetCurveParameters(me:out;
aT1 :Real from Standard;
aT2 :Real from Standard;
aPitch :Real from Standard;
aRStart :Real from Standard;
aTaperAngle :Real from Standard;
bIsClockwise :Boolean from Standard);
---Purpose: Sets parameters for building helix curves
CurveParameters(me;
aT1 :out Real from Standard;
aT2 :out Real from Standard;
aPitch :out Real from Standard;
aRStart :out Real from Standard;
aTaperAngle :out Real from Standard;
bIsClockwise :out Boolean from Standard);
---Purpose: Gets parameters for building helix curves
fields
myT1 : Real from Standard is protected;
myT2 : Real from Standard is protected;
myPitch : Real from Standard is protected;
myRStart : Real from Standard is protected;
myTaperAngle : Real from Standard is protected;
myIsClockWise: Boolean from Standard is protected;
end BuilderHelixGen;

View File

@@ -0,0 +1,58 @@
// File: HelixGeom_BuilderHelixGen.cxx
#include <HelixGeom_BuilderHelixGen.ixx>
//=======================================================================
//function :
//purpose :
//=======================================================================
HelixGeom_BuilderHelixGen::HelixGeom_BuilderHelixGen()
:
HelixGeom_BuilderApproxCurve()
{
}
//=======================================================================
//function : ~
//purpose :
//=======================================================================
HelixGeom_BuilderHelixGen::~HelixGeom_BuilderHelixGen()
{
}
//=======================================================================
//function : SetCurveParameters
//purpose :
//=======================================================================
void HelixGeom_BuilderHelixGen::SetCurveParameters(const Standard_Real aT1,
const Standard_Real aT2,
const Standard_Real aPitch,
const Standard_Real aRStart,
const Standard_Real aTaperAngle,
const Standard_Boolean aIsCW)
{
myT1=aT1;
myT2=aT2;
myPitch=aPitch;
myRStart=aRStart;
myTaperAngle=aTaperAngle;
myIsClockWise=aIsCW;
}
//=======================================================================
//function : CurveParameters
//purpose :
//=======================================================================
void HelixGeom_BuilderHelixGen::CurveParameters(Standard_Real& aT1,
Standard_Real& aT2,
Standard_Real& aPitch,
Standard_Real& aRStart,
Standard_Real& aTaperAngle,
Standard_Boolean& aIsClockWise)const
{
aT1=myT1;
aT2=myT2;
aPitch=myPitch;
aRStart=myRStart;
aTaperAngle=myTaperAngle;
aIsClockWise=myIsClockWise;
}

View File

@@ -0,0 +1,35 @@
-- File: HelixGeom_HHelixCurve.cdl
class HHelixCurve from HelixGeom
inherits GHHelixCurve from HelixGeom
---Purpose: HAdaptor class for helix curve
uses
HelixCurve from HelixGeom
--raises
is
Create
---Purpose: Empty constructor
returns HHelixCurve from HelixGeom;
Create(aC: HelixCurve from HelixGeom)
---Purpose: Constructor by corresponding adaptor curve
returns HHelixCurve from HelixGeom;
Create(aT1:Real from Standard;
aT2:Real from Standard;
aPitch:Real from Standard;
aRStart:Real from Standard;
aTaperAngle:Real from Standard;
aIsCW:Boolean from Standard)
---Purpose: Constructor by parameters
returns HHelixCurve from HelixGeom;
--fields
end HHelixCurve;

View File

@@ -0,0 +1,39 @@
// File: HelixGeom_HHelixCurve.cxx
#include <HelixGeom_HHelixCurve.ixx>
//=======================================================================
//function : HelixGeom_HHelixCurve
//purpose :
//=======================================================================
HelixGeom_HHelixCurve::HelixGeom_HHelixCurve()
{
}
//=======================================================================
//function : HelixGeom_HHelixCurve// Lastly modified by :
// +---------------------------------------------------------------------------+
// ! ifv ! Creation !$Date: 2007-10-19 18:21:42 $! %V%-%L%!
// +---------------------------------------------------------------------------+
//purpose :
//=======================================================================
HelixGeom_HHelixCurve::HelixGeom_HHelixCurve(const HelixGeom_HelixCurve& aC)
: HelixGeom_GHHelixCurve(aC)
{
}
//=======================================================================
//function : HelixGeom_HHelixCurve
//purpose :
//=======================================================================
HelixGeom_HHelixCurve::HelixGeom_HHelixCurve(const Standard_Real aT1,
const Standard_Real aT2,
const Standard_Real aPitch,
const Standard_Real aRStart,
const Standard_Real aTaperAngle,
const Standard_Boolean aIsCW)
{
ChangeCurve().Load(aT1, aT2, aPitch, aRStart, aTaperAngle, aIsCW);
}

View File

@@ -0,0 +1,140 @@
-- File: HelixGeom_HelixCurve.cdl
class HelixCurve from HelixGeom
inherits Curve from Adaptor3d
---Purpose: Adaptor class for calculation helix curve
uses
Shape from GeomAbs,
Pnt from gp,
Vec from gp,
Array1OfReal from TColStd
raises
ConstructionError from Standard,
OutOfRange from Standard,
DomainError from Standard
is
Create
---Purpose: Adaptor class for calculation helix curve
-- implementation of analytical expressions
returns HelixCurve from HelixGeom;
Load(me:out);
---Purpose: Sets default values for parameters
Load(me:out;
aT1:Real from Standard;
aT2:Real from Standard;
aPitch:Real from Standard;
aRStart:Real from Standard;
aTaperAngle:Real from Standard;
aIsCW:Boolean from Standard)
---Purpose: Sets helix parameters
raises ConstructionError from Standard;
FirstParameter(me)
---Purpose: Gets first parameter
returns Real from Standard
is redefined;
LastParameter(me)
---Purpose: Gets last parameter
returns Real from Standard
is redefined;
Continuity(me)
---Purpose: Gets continuity
returns Shape from GeomAbs
is redefined;
NbIntervals(me;
S : Shape from GeomAbs)
---Purpose: Gets number of intervals
returns Integer from Standard
is redefined;
Intervals(me;
T :out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Gets parametric intervals
is redefined;
Resolution(me; R3d :Real from Standard)
---Purpose: Gets parametric resolution
returns Real from Standard
is redefined;
IsClosed(me)
---Purpose: Returns False
returns Boolean from Standard
is redefined;
IsPeriodic(me)
---Purpose: Returns False
returns Boolean from Standard
is redefined;
Period(me)
---Purpose: Returns 2*PI
returns Real from Standard
raises DomainError from Standard
is redefined;
Value(me;
U : Real from Standard)
---Purpose: Gets curve point for parameter U
returns Pnt from gp
is redefined;
D0 (me;
U : Real from Standard;
P : out Pnt from gp)
---Purpose: Gets curve point for parameter U
is redefined;
D1 (me;
U : Real from Standard;
P : out Pnt from gp;
V1: out Vec from gp)
---Purpose: Gets curve point and first derivatives
-- for parameter U
is redefined;
D2 (me;
U : Real from Standard;
P : out Pnt from gp;
V1 : out Vec from gp;
V2 : out Vec from gp)
---Purpose: Gets curve point, first and second derivatives
-- for parameter U
is redefined;
DN (me;
U : Real from Standard;
N : Integer from Standard)
---Purpose: Gets curve derivative of demanded order
-- for parameter U
returns Vec from gp
raises OutOfRange from Standard
is redefined;
fields
myFirst : Real from Standard is protected;
myLast : Real from Standard is protected;
myPitch : Real from Standard is protected;
myRStart : Real from Standard is protected;
myTaperAngle : Real from Standard is protected;
myIsClockWise: Boolean from Standard is protected;
--
-- private
myC1 : Real from Standard is protected;
myTgBeta : Real from Standard is protected;
myTolAngle : Real from Standard is protected;
end HelixCurve;

View File

@@ -0,0 +1,288 @@
// File: HelixGeom_HelixCurve.cxx
#include <HelixGeom_HelixCurve.ixx>
#include <math.h>
#include <gp_Vec.hxx>
#include <gp_Pnt.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_DomainError.hxx>
//=======================================================================
//function : HelixGeom_HelixCurve
//purpose :
//=======================================================================
HelixGeom_HelixCurve::HelixGeom_HelixCurve()
{
myFirst=0.;
myLast=2.*M_PI;
myPitch=1.;
myRStart=1.;
myTaperAngle=0.;
myIsClockWise=Standard_True;
//
myC1=myPitch/myLast;
myTgBeta=0.;
myTolAngle=1.e-4;
}
//=======================================================================
//function : Load
//purpose :
//=======================================================================
void HelixGeom_HelixCurve::Load()
{
Load(myFirst, myLast, myPitch, myRStart, myTaperAngle, myIsClockWise);
}
//=======================================================================
//function : Load
//purpose :
//=======================================================================
void HelixGeom_HelixCurve::Load(const Standard_Real aT1,
const Standard_Real aT2,
const Standard_Real aPitch,
const Standard_Real aRStart,
const Standard_Real aTaperAngle,
const Standard_Boolean aIsCW)
{
char buf[]={"HelixGeom_HelixCurve::Load"};
Standard_Real aTwoPI, aHalfPI;
//
aTwoPI=2.*M_PI;
aHalfPI=0.5*M_PI;
//
myFirst=aT1;
myLast=aT2;
myPitch=aPitch;
myRStart=aRStart;
myTaperAngle=aTaperAngle;
myIsClockWise=aIsCW;
//
if (aT1>=aT2) {
Standard_ConstructionError::Raise(buf);
}
if (myPitch<0.) {
Standard_ConstructionError::Raise(buf);
}
if (myRStart<0.) {
Standard_ConstructionError::Raise(buf);
}
if (myTaperAngle<=-aHalfPI ||
myTaperAngle>=aHalfPI) {
Standard_ConstructionError::Raise(buf);
}
//
myC1=myPitch/aTwoPI;
if (fabs(myTaperAngle)>myTolAngle) {
myTgBeta=tan(myTaperAngle);
}
}
//=======================================================================
//function : FirstParameter
//purpose :
//=======================================================================
Standard_Real HelixGeom_HelixCurve::FirstParameter() const
{
return myFirst;
}
//=======================================================================
//function : LastParameter
//purpose :
//=======================================================================
Standard_Real HelixGeom_HelixCurve::LastParameter() const
{
return myLast;
}
//=======================================================================
//function : Continuity
//purpose :
//=======================================================================
GeomAbs_Shape HelixGeom_HelixCurve::Continuity() const
{
return GeomAbs_CN;
}
//=======================================================================
//function : NbIntervals
//purpose :
//=======================================================================
Standard_Integer HelixGeom_HelixCurve::NbIntervals(const GeomAbs_Shape ) const
{
return 1;
}
//=======================================================================
//function : Intervals
//purpose :
//=======================================================================
void HelixGeom_HelixCurve::Intervals(TColStd_Array1OfReal& T,
const GeomAbs_Shape) const
{
T(1)=myFirst;
T(2)=myLast;
}
//=======================================================================
//function : Resolution
//purpose :
//=======================================================================
Standard_Real HelixGeom_HelixCurve::Resolution(const Standard_Real) const
{
Standard_NotImplemented::Raise("HelixGeom_HelixCurve::Resolution");
return 0.;
}
//=======================================================================
//function : IsClosed
//purpose :
//=======================================================================
Standard_Boolean HelixGeom_HelixCurve::IsClosed() const
{
Standard_NotImplemented::Raise("HelixGeom_HelixCurve::IsClosed");
return Standard_False;
}
//=======================================================================
//function : IsPeriodic
//purpose :
//=======================================================================
Standard_Boolean HelixGeom_HelixCurve::IsPeriodic() const
{
Standard_NotImplemented::Raise("HelixGeom_HelixCurve::IsPeriodic");
return Standard_False;
}
//=======================================================================
//function : Period
//purpose :
//=======================================================================
Standard_Real HelixGeom_HelixCurve::Period()const
{
Standard_DomainError::Raise("HelixGeom_HelixCurve::Periodic");
return 0.;
}
//=======================================================================
//function : Value
//purpose :
//=======================================================================
gp_Pnt HelixGeom_HelixCurve::Value(const Standard_Real aT) const
{
Standard_Real aST, aCT, aX, aY, aZ, a1;
//
aCT=cos(aT);
aST=sin(aT);
a1=myRStart+myC1*myTgBeta*aT;
//
aX=a1*aCT;
aY=a1*aST;
if (!myIsClockWise) {
aY=-aY;
}
aZ=myC1*aT;
return gp_Pnt(aX, aY, aZ);
}
//=======================================================================
//function : D0
//purpose :
//=======================================================================
void HelixGeom_HelixCurve::D0(const Standard_Real aT,
gp_Pnt& aP) const
{
aP=Value(aT);
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
void HelixGeom_HelixCurve::D1(const Standard_Real aT,
gp_Pnt& aP,
gp_Vec& aV1) const
{
Standard_Real aST, aCT, aX, aY, aZ, a1, a2;
//
aCT=cos(aT);
aST=sin(aT);
//
a1=myRStart+myC1*myTgBeta*aT;
//
aX=a1*aCT;
aY=a1*aST;
if (!myIsClockWise) {
aY=-aY;
}
aZ=myC1*aT;
aP.SetCoord(aX, aY, aZ);
//
a1=myC1*myTgBeta;
a2=myRStart+a1*aT;
//
aX=a1*aCT-a2*aST;
aY=a1*aST+a2*aCT;
if (!myIsClockWise) {
aY=-aY;
}
aZ=myC1;
aV1.SetCoord(aX, aY, aZ);
}
//=======================================================================
//function : D2
//purpose :
//=======================================================================
void HelixGeom_HelixCurve::D2(const Standard_Real aT,
gp_Pnt& aP,
gp_Vec& aV1,
gp_Vec& aV2) const
{
Standard_Real aST, aCT, aX, aY, aZ, a1, a2;
//
aCT=cos(aT);
aST=sin(aT);
//
a1=myRStart+myC1*myTgBeta*aT;
//
aX=a1*aCT;
aY=a1*aST;
if (!myIsClockWise) {
aY=-aY;
}
aZ=myC1*aT;
aP.SetCoord(aX, aY, aZ);
//
a1=myC1*myTgBeta;
a2=myRStart+a1*aT;
//
aX=a1*aCT-a2*aST;
aY=a1*aST+a2*aCT;
if (!myIsClockWise) {
aY=-aY;
}
aZ=myC1;
aV1.SetCoord(aX, aY, aZ);
//
a1=2.*a1;
aX=-a2*aCT-a1*aST;
aY=-a2*aST-a1*aCT;
if (!myIsClockWise) {
aY=-aY;
}
aZ=0.;
aV2.SetCoord(aX, aY, aZ);
}
//=======================================================================
//function : DN
//purpose :
//=======================================================================
gp_Vec HelixGeom_HelixCurve::DN(const Standard_Real aT,
const Standard_Integer aN) const
{
gp_Pnt aP;
gp_Vec aV1, aV2;
//
switch (aN) {
case 1:
D1(aT, aP, aV1);
break;
case 2:
D2(aT, aP, aV1, aV2);
break;
default:
Standard_NotImplemented::Raise("HelixGeom_HelixCurve::DN");
break;
}
return gp_Vec(aV1);
}

View File

@@ -0,0 +1,42 @@
-- File: HelixGeom_Tools.cdl
class Tools from HelixGeom
---Purpose: Approximation algorithms for bulding helix curves
uses
HCurve from Adaptor3d,
BSplineCurve from Geom,
Shape from GeomAbs
--raises
is
ApprHelix(myclass;
aT1 :Real from Standard;
aT2 :Real from Standard;
aPitch :Real from Standard;
aRStart :Real from Standard;
aTaperAngle:Real from Standard;
aIsCW :Boolean from Standard;
aTol :Real from Standard;
theBSpl :out BSplineCurve from Geom;
theMaxError:out Real from Standard)
---Purpose: Bulding helix curves
returns Integer from Standard;
ApprCurve3D(myclass;
theHC :out HCurve from Adaptor3d;
theTol : Real from Standard;
theCont : Shape from GeomAbs;
theMaxSeg : Integer from Standard;
theMaxDeg : Integer from Standard;
theBSpl :out BSplineCurve from Geom;
theMaxError:out Real from Standard)
---Purpose: Reaprroximation of adaptor curve
returns Integer from Standard;
--fields
end Tools;

View File

@@ -0,0 +1,168 @@
// File: HelixGeom_Tools.cxx
#include <HelixGeom_Tools.ixx>
#include <Adaptor3d_HCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <AdvApprox_DichoCutting.hxx>
#include <AdvApprox_EvaluatorFunction.hxx>
#include <AdvApprox_ApproxAFunction.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <HelixGeom_HelixCurve.hxx>
#include <HelixGeom_HHelixCurve.hxx>
//=======================================================================
//class : HelixGeom_Tools_Eval
//purpose: evaluator class for approximation
//=======================================================================
class HelixGeom_Tools_Eval : public AdvApprox_EvaluatorFunction
{
public:
HelixGeom_Tools_Eval (const Handle(Adaptor3d_HCurve)& theFunc)
: fonct(theFunc) {}
virtual void Evaluate (Standard_Integer *Dimension,
Standard_Real StartEnd[2],
Standard_Real *Parameter,
Standard_Integer *DerivativeRequest,
Standard_Real *Result, // [Dimension]
Standard_Integer *ErrorCode);
private:
Handle(Adaptor3d_HCurve) fonct;
};
void HelixGeom_Tools_Eval::Evaluate (Standard_Integer *Dimension,
Standard_Real /*StartEnd*/[2],
Standard_Real *Param, // Parameter at which evaluation
Standard_Integer *Order, // Derivative Request
Standard_Real *Result,// [Dimension]
Standard_Integer *ErrorCode)
{
*ErrorCode = 0;
Standard_Real par = *Param;
// Dimension is incorrect
if (*Dimension!=3) {
*ErrorCode = 1;
}
gp_Pnt pnt;
gp_Vec v1, v2;
switch (*Order) {
case 0:
pnt = fonct->Value(par);
Result[0] = pnt.X();
Result[1] = pnt.Y();
Result[2] = pnt.Z();
break;
case 1:
fonct->D1(par, pnt, v1);
Result[0] = v1.X();
Result[1] = v1.Y();
Result[2] = v1.Z();
break;
case 2:
fonct->D2(par, pnt, v1, v2);
Result[0] = v2.X();
Result[1] = v2.Y();
Result[2] = v2.Z();
break;
default:
Result[0] = Result[1] = Result[2] = 0.;
*ErrorCode = 3;
break;
}
}
//=======================================================================
//function : ApprCurve3D
//purpose :
//=======================================================================
Standard_Integer HelixGeom_Tools::ApprCurve3D(Handle(Adaptor3d_HCurve)& theHC,
const Standard_Real theTol,
const GeomAbs_Shape theCont,
const Standard_Integer theMaxSeg,
const Standard_Integer theMaxDeg,
Handle(Geom_BSplineCurve)& theBSpl,
Standard_Real& theMaxError)
{
Standard_Boolean anIsDone, aHasResult;
Standard_Integer Num1DSS, Num2DSS, Num3DSS;
Standard_Real First, Last;
Handle(TColStd_HArray1OfReal) OneDTolNul, TwoDTolNul, ThreeDTol;
AdvApprox_DichoCutting aCutTool;
//
Num1DSS=0;
Num2DSS=0;
Num3DSS=1;
ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS);
ThreeDTol->Init(theTol);
//
First = theHC->FirstParameter();
Last = theHC->LastParameter();
//
HelixGeom_Tools_Eval ev (theHC);
AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS,
OneDTolNul, TwoDTolNul, ThreeDTol,
First, Last, theCont,
theMaxDeg, theMaxSeg,
ev, aCutTool);
//
anIsDone = aApprox.IsDone();
if(!anIsDone) {
return 1;
}
//
theMaxError = 0.;
//
aHasResult = aApprox.HasResult();
if (!aHasResult) {
return 2;
}
//
TColgp_Array1OfPnt Poles(1,aApprox.NbPoles());
aApprox.Poles(1,Poles);
Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots();
Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities();
Standard_Integer Degree = aApprox.Degree();
theBSpl = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree);
theMaxError = aApprox.MaxError(3, 1);
//
return 0;
}
//=======================================================================
//function : ApprHelix
//purpose :
//=======================================================================
Standard_Integer HelixGeom_Tools::ApprHelix(const Standard_Real aT1,
const Standard_Real aT2,
const Standard_Real aPitch,
const Standard_Real aRStart,
const Standard_Real aTaperAngle,
const Standard_Boolean aIsCW,
const Standard_Real theTol,
Handle(Geom_BSplineCurve)& theBSpl,
Standard_Real& theMaxError)
{
Standard_Integer iErr, aMaxDegree, aMaxSeg;
GeomAbs_Shape aCont;
HelixGeom_HelixCurve aAdaptor;
Handle(HelixGeom_HHelixCurve) aHAdaptor;
//
aAdaptor.Load(aT1, aT2, aPitch, aRStart, aTaperAngle, aIsCW);
aHAdaptor=new HelixGeom_HHelixCurve(aAdaptor);
//
aCont=GeomAbs_C2;
aMaxDegree = 8;
aMaxSeg=150;
//
iErr=HelixGeom_Tools::ApprCurve3D(aHAdaptor,
theTol, aCont, aMaxSeg, aMaxDegree,
theBSpl, theMaxError);
return iErr;
}

2
src/HelixTest/FILES Normal file
View File

@@ -0,0 +1,2 @@
HelixTest.cxx
HelixTest_HelixCommands.cxx

View File

@@ -0,0 +1,19 @@
-- File: HelixTest.cdl
package HelixTest
---Purpose:
uses
Draw,
DBRep,
TopoDS,
gp
is
AllCommands (aDI:out Interpretor from Draw);
HelixCommands (aDI:out Interpretor from Draw);
Factory (aDI:out Interpretor from Draw);
end HelixTest;

View File

@@ -0,0 +1,35 @@
// File: HelixTest.cxx
#include <HelixTest.ixx>
#include <stdio.h>
//=======================================================================
//function : AllCommands
//purpose :
//=======================================================================
void HelixTest::AllCommands(Draw_Interpretor& theCommands)
{
static Standard_Boolean done = Standard_False;
if (done) return;
done = Standard_True;
//
HelixTest::HelixCommands (theCommands);
}
//=======================================================================
//function : Factory
//purpose :
//=======================================================================
void HelixTest::Factory(Draw_Interpretor& theCommands)
{
static Standard_Boolean FactoryDone = Standard_False;
if (FactoryDone) return;
FactoryDone = Standard_True;
HelixTest::AllCommands(theCommands);
Printf(" Helix Plugin is loaded\n");
}
#include <Draw_PluginMacro.hxx>
DPLUGIN(HelixTest)

View File

@@ -0,0 +1,559 @@
// File: HelixTest_HelixCommands.cxx
#include <HelixTest.ixx>
#include <Draw_Interpretor.hxx>
#include <HelixGeom_HelixCurve.hxx>
#include <Draw.hxx>
#include <Draw_Viewer.hxx>
#include <Draw_Marker3D.hxx>
#include <Draw_Segment3D.hxx>
#include <Draw_Color.hxx>
#include <HelixGeom_Tools.hxx>
#include <DrawTrSurf.hxx>
#include <TCollection_AsciiString.hxx>
#include <HelixGeom_BuilderHelixCoil.hxx>
#include <TColGeom_SequenceOfCurve.hxx>
#include <HelixGeom_BuilderHelix.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_Surface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Line.hxx>
#include <gp_Pln.hxx>
#include <gp_Ax1.hxx>
#include <gp_Dir.hxx>
#include <gp_Ax2.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <HelixBRep_BuilderHelix.hxx>
#include <DBRep.hxx>
#include <TopoDS_Shape.hxx>
#include <gp.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <TColGeom_HArray1OfCurve.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfBoolean.hxx>
//
Standard_IMPORT Draw_Viewer dout;
//
static gp_Ax3 theHelixAxis(gp_Pnt(0., 0., 0), gp_Dir(0., 0., 1.), gp_Dir(1., 0., 0.));
static Standard_Integer comphelix (Draw_Interpretor& , Standard_Integer , const char ** );
static Standard_Integer helix (Draw_Interpretor& , Standard_Integer , const char ** );
static Standard_Integer spiral (Draw_Interpretor& , Standard_Integer , const char ** );
static Standard_Integer setaxis (Draw_Interpretor& , Standard_Integer , const char ** );
static Standard_Integer comphelix2 (Draw_Interpretor& , Standard_Integer , const char ** );
static Standard_Integer helix2 (Draw_Interpretor& , Standard_Integer , const char ** );
static Standard_Integer spiral2 (Draw_Interpretor& , Standard_Integer , const char ** );
//=======================================================================
//function : HelixTest::HelixCommands
//purpose :
//=======================================================================
void HelixTest::HelixCommands(Draw_Interpretor& theCommands)
{
static Standard_Boolean done = Standard_False;
if (done) return;
done = Standard_True;
// Chapters name
const char* g = "Helix commands";
// Commands
theCommands.Add("setaxis", "setaxis x y z Nx Ny Nz Xx Xy Xz",
__FILE__, setaxis, g);
theCommands.Add("comphelix", "comphelix name np D1 [Di...] H1 [Hi...] P1 [Pi...] PF1 [PFi...]",
__FILE__, comphelix, g);
theCommands.Add("helix", "helix name np D1 H1 [Hi...] P1 [Pi...] PF1 [PFi...]",
__FILE__, helix, g);
theCommands.Add("spiral", "spiral name np D1 D2 H1 [Hi...] P1 [Pi...] PF1 [PFi...]",
__FILE__, spiral, g);
theCommands.Add("comphelix2", "comphelix2 name np D1 [Di...] P1 [Pi...] N1 [Ni...]",
__FILE__, comphelix2, g);
theCommands.Add("helix2", "helix2 name np D1 P1 [Pi...] N1 [Ni...]",
__FILE__, helix2, g);
theCommands.Add("spiral2", "spiral2 name np D1 D2 P1 [Pi...] N1 [Ni...]",
__FILE__, spiral2, g);
}
//=======================================================================
//function : setaxis
//purpose :
//=======================================================================
Standard_Integer setaxis(Draw_Interpretor& di, Standard_Integer n, const char ** a)
{
if (n < 10) {
di << "Usage : " << a[0] << " x y z Nx Ny Nz Xx Xy Xz" <<"\n";
di << " " << "x y z - location" <<"\n";
di << " " << "Nx Ny Nz - direction" <<"\n";
di << " " << "Xx Xy Xz - X direction" <<"\n";
return 1;
}
Standard_Real xx[9];
Standard_Integer i;
for(i = 0; i < 9; ++i) {
xx[i] = Draw::Atof(a[i+1]);
}
theHelixAxis.SetLocation(gp_Pnt(xx[0], xx[1], xx[2]));
theHelixAxis.SetDirection(gp_Dir(xx[3], xx[4], xx[5]));
theHelixAxis.SetXDirection(gp_Dir(xx[6], xx[7], xx[8]));
return 0;
}
//
//=======================================================================
//function : comphelix
//purpose :
//=======================================================================
Standard_Integer comphelix(Draw_Interpretor& di, Standard_Integer n, const char ** a)
{
if (n < 8) {
di << "Usage : " << a[0] << " name np D1 D2 [Di...] H1 [Hi...] P1 [Pi...] PF1 [PFi...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 D2 ... (must be np+1 values) - diameters" <<"\n";
di << " " << "H1, H2 ... (must be np values) - heights" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches or numbers of turns" <<"\n";
di << " " << "PF1, PF2 ... (must be np values) - 0 or 1, if PFi = 1, Pi is pitch, otherwise Pi is number of turns" <<"\n";
return 1;
}
//
Standard_Integer i, aNb, ic;
HelixBRep_BuilderHelix aBH;
//
aNb = Draw::Atoi(a[2]);
if (n != 3 + (aNb+1) + aNb*3) {
di << "Usage : " << a[0] << " name np D1 D2 [Di...] H1 [Hi...] P1 [Pi...] PF1 [PFi...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 D2 ... (must be np+1 values) - diameters" <<"\n";
di << " " << "H1, H2 ... (must be np values) - heights" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches or numbers of turns" <<"\n";
di << " " << "PF1, PF2 ... (must be np values) - 0 or 1, if PFi = 1, Pi is pitch, otherwise Pi is number of turns" <<"\n";
return 1;
}
//
TColStd_Array1OfReal aDiams(1, aNb + 1);
TColStd_Array1OfReal aHeights(1, aNb);
TColStd_Array1OfReal aPitches(1, aNb);
TColStd_Array1OfBoolean bIsPitches(1, aNb);
ic = 3;
for(i = 1; i <= aNb+1; ++i) {
aDiams(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aHeights(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aPitches(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
bIsPitches(i) = Draw::Atoi(a[ic]);
++ic;
}
//
aBH.SetParameters(theHelixAxis, aDiams, aHeights, aPitches, bIsPitches);
aBH.Perform();
if(aBH.ErrorStatus() == 0) {
Standard_Real aMaxError=aBH.ToleranceReached();
di << "WarningStatus = " << aBH.WarningStatus() <<"\n";
di << "ToleranceReached = " << aMaxError <<"\n";
//
const TopoDS_Shape& aW=aBH.Shape();
DBRep::Set(a[1], aW);
}
else {
di << "ErrorStatus = " << aBH.ErrorStatus() << "\n";
}
return 0;
}
//=======================================================================
//function : helix
//purpose :
//=======================================================================
Standard_Integer helix(Draw_Interpretor& di, Standard_Integer n, const char ** a)
{
if (n < 7) {
di << "Usage : " << a[0] << " name np D1 H1 [Hi...] P1 [Pi...] PF1 [PFi...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 - diameter" <<"\n";
di << " " << "H1, H2 ... (must be np values) - heights" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches or numbers of turns" <<"\n";
di << " " << "PF1, PF2 ... (must be np values) - 0 or 1, if PFi = 1, Pi is pitch, otherwise Pi is number of turns" <<"\n";
return 1;
}
//
Standard_Integer i, aNb, ic;
HelixBRep_BuilderHelix aBH;
//
aNb = Draw::Atoi(a[2]);
if (n != 3 + 1 + aNb*3) {
di << "Usage : " << a[0] << " name np D1 H1 [Hi...] P1 [Pi...] PF1 [PFi...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 - diameter" <<"\n";
di << " " << "H1, H2 ... (must be np values) - heights" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches or numbers of turns" <<"\n";
di << " " << "PF1, PF2 ... (must be np values) - 0 or 1, if PFi = 1, Pi is pitch, otherwise Pi is number of turns" <<"\n";
return 1;
}
//
TColStd_Array1OfReal aDiams(1, 1);
TColStd_Array1OfReal aHeights(1, aNb);
TColStd_Array1OfReal aPitches(1, aNb);
TColStd_Array1OfBoolean bIsPitches(1, aNb);
ic = 3;
for(i = 1; i <= 1; ++i) {
aDiams(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aHeights(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aPitches(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
bIsPitches(i) = Draw::Atoi(a[ic]);
++ic;
}
//
aBH.SetParameters(theHelixAxis, aDiams(1), aHeights, aPitches, bIsPitches);
aBH.Perform();
if(aBH.ErrorStatus() == 0) {
Standard_Real aMaxError=aBH.ToleranceReached();
di << "WarningStatus = " << aBH.WarningStatus() <<"\n";
di << "ToleranceReached = " << aMaxError <<"\n";
//
const TopoDS_Shape& aW=aBH.Shape();
DBRep::Set(a[1], aW);
}
else {
di << "ErrorStatus = " << aBH.ErrorStatus() << "\n";
}
return 0;
}
//=======================================================================
//function : spiral
//purpose :
//=======================================================================
Standard_Integer spiral(Draw_Interpretor& di, Standard_Integer n, const char ** a)
{
if (n < 8) {
di << "Usage : " << a[0] << " name np D1 D2 H1 [Hi...] P1 [Pi...] PF1 [PFi...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 D2 - first and last diameters" <<"\n";
di << " " << "H1, H2 ... (must be np values) - heights" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches or numbers of turns" <<"\n";
di << " " << "PF1, PF2 ... (must be np values) - 0 or 1, if PFi = 1, Pi is pitch, otherwise Pi is number of turns" <<"\n";
return 1;
}
//
Standard_Integer i, aNb, ic;
HelixBRep_BuilderHelix aBH;
//
aNb = Draw::Atoi(a[2]);
if (n != 3 + 2 + aNb*3) {
di << "Usage : " << a[0] << " name np D1 D2 H1 [Hi...] P1 [Pi...] PF1 [PFi...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 D2 - first and last diameters" <<"\n";
di << " " << "H1, H2 ... (must be np values) - heights" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches or numbers of turns" <<"\n";
di << " " << "PF1, PF2 ... (must be np values) - 0 or 1, if PFi = 1, Pi is pitch, otherwise Pi is number of turns" <<"\n";
return 1;
}
//
TColStd_Array1OfReal aDiams(1, 2);
TColStd_Array1OfReal aHeights(1, aNb);
TColStd_Array1OfReal aPitches(1, aNb);
TColStd_Array1OfBoolean bIsPitches(1, aNb);
ic = 3;
for(i = 1; i <= 2; ++i) {
aDiams(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aHeights(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aPitches(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
bIsPitches(i) = Draw::Atoi(a[ic]);
++ic;
}
//
aBH.SetParameters(theHelixAxis, aDiams(1), aDiams(2), aHeights, aPitches, bIsPitches);
aBH.Perform();
if(aBH.ErrorStatus() == 0) {
Standard_Real aMaxError=aBH.ToleranceReached();
di << "WarningStatus = " << aBH.WarningStatus() <<"\n";
di << "ToleranceReached = " << aMaxError <<"\n";
//
const TopoDS_Shape& aW=aBH.Shape();
DBRep::Set(a[1], aW);
}
else {
di << "ErrorStatus = " << aBH.ErrorStatus() << "\n";
}
return 0;
}
//=======================================================================
//function : comphelix2
//purpose :
//=======================================================================
Standard_Integer comphelix2(Draw_Interpretor& di, Standard_Integer n, const char ** a)
{
if (n < 7) {
di << "Usage : " << a[0] << " name np D1 D2 [Di...] P1 [Pi...] N1 [Ni...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 D2, ... (must be np+1 values) - diameters" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches" <<"\n";
di << " " << "N1, N2, ... (must be np values) - numbers of turns" <<"\n";
return 1;
}
//
Standard_Integer i, aNb, ic;
HelixBRep_BuilderHelix aBH;
//
aNb = Draw::Atoi(a[2]);
if (n != 3 + (aNb+1) + aNb*2) {
di << "Usage : " << a[0] << " name np D1 D2 [Di...] P1 [Pi...] N1 [Ni...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 D2, ... (must be np+1 values) - diameters" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches" <<"\n";
di << " " << "N1, N2, ... (must be np values) - numbers of turns" <<"\n";
return 1;
}
//
TColStd_Array1OfReal aDiams(1, aNb + 1);
TColStd_Array1OfReal aPitches(1, aNb);
TColStd_Array1OfReal aNbTurns(1, aNb);
ic = 3;
for(i = 1; i <= aNb+1; ++i) {
aDiams(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aPitches(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aNbTurns(i) = Draw::Atof(a[ic]);
++ic;
}
//
aBH.SetParameters(theHelixAxis, aDiams, aPitches, aNbTurns);
aBH.Perform();
if(aBH.ErrorStatus() == 0) {
Standard_Real aMaxError=aBH.ToleranceReached();
di << "WarningStatus = " << aBH.WarningStatus() <<"\n";
di << "ToleranceReached = " << aMaxError <<"\n";
//
const TopoDS_Shape& aW=aBH.Shape();
DBRep::Set(a[1], aW);
}
else {
di << "ErrorStatus = " << aBH.ErrorStatus() << "\n";
}
return 0;
}
//=======================================================================
//function : helix2
//purpose :
//=======================================================================
Standard_Integer helix2(Draw_Interpretor& di, Standard_Integer n, const char ** a)
{
if (n < 6) {
di << "Usage : " << a[0] << " name np D1 P1 [Pi...] N1 [Ni...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 - diameter" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches" <<"\n";
di << " " << "N1, N2, ... (must be np values) - numbers of turns" <<"\n";
return 1;
}
//
Standard_Integer i, aNb, ic;
HelixBRep_BuilderHelix aBH;
//
aNb = Draw::Atoi(a[2]);
if (n != 3 + 1 + aNb*2) {
di << "Usage : " << a[0] << " name np D1 H1 [Hi...] P1 [Pi...] PF1 [PFi...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 - diameter" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches" <<"\n";
di << " " << "N1, N2, ... (must be np values) - numbers of turns" <<"\n";
return 1;
}
//
TColStd_Array1OfReal aDiams(1, 1);
TColStd_Array1OfReal aPitches(1, aNb);
TColStd_Array1OfReal aNbTurns(1, aNb);
ic = 3;
for(i = 1; i <= 1; ++i) {
aDiams(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aPitches(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aNbTurns(i) = Draw::Atof(a[ic]);
++ic;
}
//
aBH.SetParameters(theHelixAxis, aDiams(1), aPitches, aNbTurns);
aBH.Perform();
if(aBH.ErrorStatus() == 0) {
Standard_Real aMaxError=aBH.ToleranceReached();
di << "WarningStatus = " << aBH.WarningStatus() <<"\n";
di << "ToleranceReached = " << aMaxError <<"\n";
//
const TopoDS_Shape& aW=aBH.Shape();
DBRep::Set(a[1], aW);
}
else {
di << "ErrorStatus = " << aBH.ErrorStatus() << "\n";
}
return 0;
}
//=======================================================================
//function : spiral2
//purpose :
//=======================================================================
Standard_Integer spiral2(Draw_Interpretor& di, Standard_Integer n, const char ** a)
{
if (n < 7) {
di << "Usage : " << a[0] << " name np D1 D2 P1 [Pi...] N1 [Ni...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 D2 - first and last diameters" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches" <<"\n";
di << " " << "N1, N2, ... (must be np values) - numbers of turns" <<"\n";
return 1;
}
//
Standard_Integer i, aNb, ic;
HelixBRep_BuilderHelix aBH;
//
aNb = Draw::Atoi(a[2]);
if (n != 3 + 2 + aNb*2) {
di << "Usage : " << a[0] << " name np D1 D2 H1 [Hi...] P1 [Pi...] PF1 [PFi...]" <<"\n";
di << " " << "name - name of result" <<"\n";
di << " " << "np - number of helix parts" <<"\n";
di << " " << "D1 D2 - first and last diameters" <<"\n";
di << " " << "P1, P2, ... (must be np values) - pitches" <<"\n";
di << " " << "N1, N2, ... (must be np values) - numbers of turns" <<"\n";
return 1;
}
//
TColStd_Array1OfReal aDiams(1, 2);
TColStd_Array1OfReal aPitches(1, aNb);
TColStd_Array1OfReal aNbTurns(1, aNb);
ic = 3;
for(i = 1; i <= 2; ++i) {
aDiams(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aPitches(i) = Draw::Atof(a[ic]);
++ic;
}
for(i = 1; i <= aNb; ++i) {
aNbTurns(i) = Draw::Atof(a[ic]);
++ic;
}
//
aBH.SetParameters(theHelixAxis, aDiams(1), aDiams(2), aPitches, aNbTurns);
aBH.Perform();
if(aBH.ErrorStatus() == 0) {
Standard_Real aMaxError=aBH.ToleranceReached();
di << "WarningStatus = " << aBH.WarningStatus() <<"\n";
di << "ToleranceReached = " << aMaxError <<"\n";
//
const TopoDS_Shape& aW=aBH.Shape();
DBRep::Set(a[1], aW);
}
else {
di << "ErrorStatus = " << aBH.ErrorStatus() << "\n";
}
return 0;
}

View File

@@ -6,3 +6,5 @@ srcinc:::ModelingData.tcl
srcinc:::Visualization.tcl
srcinc:::ApplicationFramework.tcl
srcinc:::DataExchange.tcl
srcinc:::Helix.tcl
srcinc:::Unfolding.tcl

36
src/OS/Helix.tcl Normal file
View File

@@ -0,0 +1,36 @@
# Definitions for a product: Helix
# List of toolkits
proc Helix:toolkits { } {
return [list TKHelix]
}
# List of non-toolkits (resource units, executables etc., with associated info)
proc Helix:ressources { } {
return {}
}
# Product name
proc Helix:name { } {
return Helix
}
# And short alias
proc Helix:alias { } {
return Helix
}
# Dependency on other products
proc Helix:depends { } {
return {}
}
proc Helix:CompileWith { } {
}
proc Helix:LinksoWith { } {
}
proc Helix:Export { } {
return [list source runtime wokadm api]
}

View File

@@ -22,6 +22,8 @@ proc OS:Modules { {plat ""} } {
ApplicationFramework \
DataExchange \
Draw \
Helix \
Unfolding \
]
return $ret
}

36
src/OS/Unfolding.tcl Normal file
View File

@@ -0,0 +1,36 @@
# Definitions for a product: Unfolding
# List of toolkits
proc Unfolding:toolkits { } {
return [list TKUnfolding TKUnfoldingTest]
}
# List of non-toolkits (resource units, executables etc., with associated info)
proc Unfolding:ressources { } {
return {}
}
# Product name
proc Unfolding:name { } {
return Unfolding
}
# And short alias
proc Unfolding:alias { } {
return Unfolding
}
# Dependency on other products
proc Unfolding:depends { } {
return {}
}
proc Unfolding:CompileWith { } {
}
proc Unfolding:LinksoWith { } {
}
proc Unfolding:Export { } {
return [list source runtime wokadm api]
}

View File

@@ -3270,47 +3270,6 @@ struct OCC25545_Functor
mutable volatile int myIsRaceDetected;
};
//=======================================================================
//function : OCC25545
//purpose : Tests data race when concurrently accessing TopLoc_Location::Transformation()
//=======================================================================
#ifdef HAVE_TBB
static Standard_Integer OCC25545 (Draw_Interpretor& di,
Standard_Integer,
const char **)
{
// Place vertices in a vector, giving the i-th vertex the
// transformation that translates it on the vector (i,0,0) from the origin.
size_t n = 1000;
std::vector<TopoDS_Shape> aShapeVec (n);
std::vector<TopLoc_Location> aLocVec (n);
TopoDS_Shape aShape = BRepBuilderAPI_MakeVertex (gp::Origin ());
aShapeVec[0] = aShape;
for (size_t i = 1; i < n; ++i) {
gp_Trsf aT;
aT.SetTranslation (gp_Vec (1, 0, 0));
aLocVec[i] = aLocVec[i - 1] * aT;
aShapeVec[i] = aShape.Moved (aLocVec[i]);
}
// Evaluator function will access vertices geometry
// concurrently
OCC25545_Functor aFunc(aShapeVec);
//concurrently process
tbb::parallel_for (size_t (0), n, aFunc, tbb::simple_partitioner ());
QVERIFY (!aFunc.myIsRaceDetected);
return 0;
}
#else
static Standard_Integer OCC25545 (Draw_Interpretor&,
Standard_Integer,
const char **argv)
{
cout << "Test skipped: command " << argv[0] << " requires TBB library" << endl;
return 0;
}
#endif
//=======================================================================
//function : OCC25547
@@ -4368,10 +4327,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands) {
theCommands.Add ("OCC25348", "OCC25348", __FILE__, OCC25348, group);
theCommands.Add ("OCC25413", "OCC25413 shape", __FILE__, OCC25413, group);
theCommands.Add ("OCC25446", "OCC25446 res b1 b2 op", __FILE__, OCC25446, group);
theCommands.Add ("OCC25545",
"no args; tests data race when concurrently accessing \n"
"\t\tTopLoc_Location::Transformation()",
__FILE__, OCC25545, group);
theCommands.Add ("OCC25547", "OCC25547", __FILE__, OCC25547, group);
theCommands.Add ("OCC24881", "OCC24881 shape", __FILE__, OCC24881, group);
theCommands.Add ("OCC26172", "OCC26172", __FILE__, OCC26172, group);

7
src/TKHelix/EXTERNLIB Normal file
View File

@@ -0,0 +1,7 @@
TKBRep
TKMath
TKernel
TKG2d
TKG3d
TKDraw
TKTopAlgo

1
src/TKHelix/FILES Normal file
View File

@@ -0,0 +1 @@
EXTERNLIB

3
src/TKHelix/PACKAGES Normal file
View File

@@ -0,0 +1,3 @@
HelixGeom
HelixBRep
HelixTest

10
src/TKUnfolding/EXTERNLIB Normal file
View File

@@ -0,0 +1,10 @@
TKBRep
TKMath
TKernel
TKG2d
TKG3d
TKDraw
TKTopAlgo
TKGeomAlgo
TKShHealing
TKGeomBase

1
src/TKUnfolding/FILES Normal file
View File

@@ -0,0 +1 @@
EXTERNLIB

1
src/TKUnfolding/PACKAGES Normal file
View File

@@ -0,0 +1 @@
Unfolding

View File

@@ -0,0 +1,6 @@
TKBRep
TKMath
TKernel
TKG3d
TKDraw
TKUnfolding

View File

@@ -0,0 +1 @@
EXTERNLIB

View File

@@ -0,0 +1 @@
UnfoldingTest

View File

@@ -0,0 +1,90 @@
-- File: Unfolding.cdl
-- Created: Tue Jul 22 12:48:05 2008
-- Author: Sergey KHROMOV
-- <skv@dimox>
---Copyright: Open CASCADE 2008
package Unfolding
---Purpose: This package contains a tool for unfolding a surface on a plane.
uses
TopoDS,
TopTools,
gp,
Standard,
TCollection,
TColgp,
math
is
---Purpose: Enumeration that defines an error status of an operation.
enumeration ErrorStatus
is
Done,
NotDone,
Failure,
InvalidSurface,
InvalidInput,
InvalidShape,
ComplexShape
end;
class Surface;
class Point;
class FunctionWithDerivative;
class Shell;
class FaceDataContainer;
class FaceDataMapHasher;
class Array2OfPoint
instantiates Array2 from TCollection (Point from Unfolding);
class HArray2OfPoint
instantiates HArray2 from TCollection (Point from Unfolding,
Array2OfPoint from Unfolding);
class IndexedMapOfFaceDataContainer
instantiates IndexedMap from TCollection
(FaceDataContainer from Unfolding,
FaceDataMapHasher from Unfolding);
ToShell(theShape : Shape from TopoDS;
theTolerance : Real from Standard;
theStatus : out ErrorStatus from Unfolding)
---Purpose: This method converts theShape to a shell. It sewes faces of the
-- shell if it is necessary and possible with the given tolerance.
-- If it is not possible to construct a single shell from theShape,
-- this method returns null shell and the corresponding error
-- status. The status can have the following values:
-- - Unfolding_Done: the operation succeeded
-- - Unfolding_InvalidInput: input shape type is less then
-- TopAbs_SHELL.
-- - Unfolding_Failure: sewing failure.
-- - Unfolding_InvalidShape: the shape after sewing does not
-- contain shells.
-- - Unfolding_ComplexShape: the shape after sewing contains
-- either more then one shell or one shell and other not
-- connected shapes.
returns Shell from TopoDS;
NbSamples(theEdge : Edge from TopoDS;
theFaces : ListOfShape from TopTools;
theTolerance: Real from Standard)
---Purpose: This method returns the number of sample points for theEdge.
-- theFaces is a list of faces that contain theEdge.
returns Integer from Standard;
GetMaxNbSamples
---Purpose: This method returns the maximal number of points for sampling of
-- edges and/or faces.
---C++: inline
returns Integer from Standard;
end Unfolding;

162
src/Unfolding/Unfolding.cxx Normal file
View File

@@ -0,0 +1,162 @@
// File: Unfolding.cxx
// Created: Wed Sep 17 09:16:05 2008
// Author: Sergey KHROMOV
// <skv@kurox>
#include <Unfolding.hxx>
#include <BRepBuilderAPI_Sewing.hxx>
#include <BRep_Tool.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS.hxx>
#include <TopTools_ListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
//=======================================================================
//function : ToShell
//purpose :
//=======================================================================
TopoDS_Shell Unfolding::ToShell(const TopoDS_Shape &theShape,
const Standard_Real theTolerance,
Unfolding_ErrorStatus &theStatus)
{
TopoDS_Shell aShell;
TopAbs_ShapeEnum aType = theShape.ShapeType();
if (aType != TopAbs_COMPOUND && aType != TopAbs_COMPSOLID &&
aType != TopAbs_SOLID && aType != TopAbs_SHELL) {
theStatus = Unfolding_InvalidInput;
return aShell;
}
if (aType == TopAbs_SHELL) {
// theShape is a shell. Nothing to be done.
theStatus = Unfolding_Done;
aShell = TopoDS::Shell(theShape);
return aShell;
}
BRepBuilderAPI_Sewing aSewing(theTolerance);
aSewing.Add(theShape);
aSewing.Perform();
const TopoDS_Shape &aShape = aSewing.SewedShape();
if (aShape.IsNull()) {
theStatus = Unfolding_Failure;
return aShell;
}
// Explore shape to extract a shell.
TopExp_Explorer anExp(aShape, TopAbs_SHELL);
if (!anExp.More()) {
theStatus = Unfolding_InvalidShape;
return aShell;
}
TopoDS_Shape aSingleShell = anExp.Current();
anExp.Next();
if (anExp.More()) {
theStatus = Unfolding_ComplexShape;
return aShell;
}
// Check if there is no other redundant shapes that are not in the shell.
anExp.Init(aShape, TopAbs_VERTEX, TopAbs_SHELL);
if (anExp.More()) {
theStatus = Unfolding_ComplexShape;
return aShell;
}
// Get the single shell.
theStatus = Unfolding_Done;
aShell = TopoDS::Shell(aSingleShell);
return aShell;
}
//=======================================================================
//function : ToShell
//purpose :
//=======================================================================
Standard_Integer Unfolding::NbSamples(const TopoDS_Edge &theEdge,
const TopTools_ListOfShape &theFaces,
const Standard_Real theTolerance)
{
Standard_Integer aNbPointsLimit = Unfolding::GetMaxNbSamples() / 2;
Standard_Integer aMaxNbPoints = 11;
Standard_Integer aNbPoints;
TopTools_ListIteratorOfListOfShape anIt( theFaces );
for ( ; anIt.More(); anIt.Next() ) {
TopoDS_Shape aCurShape = anIt.Value();
TopoDS_Face aFace = TopoDS::Face( aCurShape );
aFace.Orientation(TopAbs_FORWARD);
Standard_Integer aNbPnt = 2;
Standard_Real aParam[2];
Handle(Geom2d_Curve) aCurve =
BRep_Tool::CurveOnSurface(theEdge, aFace, aParam[0], aParam[1]);
Handle(Standard_Type) aType = aCurve->DynamicType();
while (aType == STANDARD_TYPE(Geom2d_TrimmedCurve)) {
Handle(Geom2d_TrimmedCurve) aTrCurve =
Handle(Geom2d_TrimmedCurve)::DownCast(aCurve);
aCurve = aTrCurve->BasisCurve();
aType = aCurve->DynamicType();
}
if (aType == STANDARD_TYPE(Geom2d_BezierCurve)) {
Handle(Geom2d_BezierCurve) aBezier =
Handle(Geom2d_BezierCurve)::DownCast(aCurve);
aNbPnt = 3 + aBezier->NbPoles();
if (aNbPnt < 11)
aNbPnt = 11;
} else if (aType == STANDARD_TYPE(Geom2d_BSplineCurve)) {
Handle(Geom2d_BSplineCurve) aBSpline =
Handle(Geom2d_BSplineCurve)::DownCast(aCurve);
aNbPnt = aBSpline->NbKnots()*aBSpline->Degree();
if (aNbPnt < 11)
aNbPnt = 11;
} else {
aNbPnt = 11;
}
aMaxNbPoints = ( aMaxNbPoints < aNbPnt ) ? aNbPnt : aMaxNbPoints;
Geom2dAdaptor_Curve aCurve1(aCurve);
Standard_Real L = GCPnts_AbscissaPoint::Length(aCurve1, aParam[0], aParam[1]) ;
// estimate number of points taking into account the curvature of radius myTolContour * 2.
Standard_Real sizeR = 0.125 * L / theTolerance + 2;
if ( aNbPointsLimit > sizeR )
aNbPointsLimit = (Standard_Integer) sizeR;
}
// Check if the number of points exceeds the maximum number of points.
if(aMaxNbPoints > aNbPointsLimit)
aMaxNbPoints = aNbPointsLimit;
aNbPoints = aMaxNbPoints;
return aNbPoints;
}

View File

@@ -0,0 +1,12 @@
// File: Unfolding.lxx
// Created: Tue Jul 22 13:12:24 2008
// Author: Sergey KHROMOV
// <skv@dimox>
inline Standard_Integer Unfolding::GetMaxNbSamples()
{
static Standard_Integer aMaxNbSamples = 1000;
return aMaxNbSamples;
}

View File

@@ -0,0 +1,89 @@
-- File: Unfolding_FaceDataContainer.cdl
-- Created: Fri Sep 19 16:52:05 2008
-- Author: Sergey KHROMOV
-- <skv@kurox>
---Copyright: Matra Datavision 2008
class FaceDataContainer from Unfolding inherits TShared from MMgt
---Purpose: This class represents a data container for data constructed
-- during unfolding operation.
uses
Face from TopoDS,
Edge from TopoDS,
Trsf from gp,
Real from Standard,
ListOfShape from TopTools,
DataMapOfShapeListOfShape from TopTools
is
Create
---Purpose: Empty constructor
---C++: inline
returns FaceDataContainer from Unfolding;
SetFace(me: mutable; theFace: Face from TopoDS);
---Purpose: Sets the original face.
GetFace(me)
---Purpose: Returns the original face.
---C++: inline
---C++: return const &
returns Face from TopoDS;
SetUnfoldedFace(me: mutable; theUnfoldedFace: Face from TopoDS);
---Purpose: Sets the unfolded face for the original one.
---C++: inline
GetUnfoldedFace(me)
---Purpose: Returns the unfolded face for the original one.
---C++: inline
---C++: return const &
returns Face from TopoDS;
SetDistortionArea(me: mutable; theDistortionArea: Real from Standard);
---Purpose: Sets the distortion area.
---C++: inline
GetDistortionArea(me)
---Purpose: Returns the distortion area.
---C++: inline
returns Real from Standard;
SetMaxGaussCurvature(me: mutable; theCurvature: Real from Standard);
---Purpose: Sets the maximal Gauss curvature.
---C++: inline
GetMaxGaussCurvature(me)
---Purpose: Returns the maximal Gauss curvature.
---C++: inline
returns Real from Standard;
Reset(me: mutable);
---Purpose: Resets the data container.
---C++: inline
ApplyTrsf(me: mutable; theTrsf: Trsf from gp);
---Purpose: Applies the transformation to all unfolded shapes.
SetEdgesForEdge(me: mutable;
theEdge : Edge from TopoDS;
theUnfoldedEdges: ListOfShape from TopTools);
---Purpose: Associates unfolded edges with the source edge.
GetEdgesForEdge(me; theEdge: Edge from TopoDS)
---Purpose: Returns unfolded edges associated to the source edge.
---C++: return const &
returns ListOfShape from TopTools;
fields
myFace : Face from TopoDS;
myUnfoldedFace : Face from TopoDS;
myEdgeMap : DataMapOfShapeListOfShape from TopTools;
myDistortionArea : Real from Standard;
myCurvature : Real from Standard;
end;

View File

@@ -0,0 +1,111 @@
// File: Unfolding_FaceDataContainer.cxx
// Created: Tue Jul 22 13:12:24 2008
// Author: Sergey KHROMOV
// <skv@dimox>
#include <Unfolding_FaceDataContainer.ixx>
#include <BRepBuilderAPI_Transform.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
//=======================================================================
//function : SetFace
//purpose :
//=======================================================================
void Unfolding_FaceDataContainer::SetFace(const TopoDS_Face &theFace)
{
Standard_Boolean isSame = theFace.IsSame(myFace);
myFace = theFace;
if (!isSame) {
// Update the map myEdgeMap
myEdgeMap.Clear();
TopExp_Explorer anExp(myFace, TopAbs_EDGE);
TopTools_ListOfShape anEmptyList;
for (; anExp.More(); anExp.Next()) {
const TopoDS_Shape &anEdge = anExp.Current();
myEdgeMap.Bind(anEdge, anEmptyList);
}
}
}
//=======================================================================
//function : ApplyTrsf
//purpose :
//=======================================================================
void Unfolding_FaceDataContainer::ApplyTrsf(const gp_Trsf &theTrsf)
{
BRepBuilderAPI_Transform aTrsf(theTrsf);
if (!myUnfoldedFace.IsNull()) {
aTrsf.Perform(myUnfoldedFace);
if (aTrsf.IsDone())
myUnfoldedFace = TopoDS::Face(aTrsf.Shape());
}
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape anEdgeIter(myEdgeMap);
TopTools_ListIteratorOfListOfShape aUEIter;
for (; anEdgeIter.More(); anEdgeIter.Next()) {
const TopoDS_Shape &anEdge = anEdgeIter.Key();
TopTools_ListOfShape &anEdges = myEdgeMap.ChangeFind(anEdge);
TopTools_ListOfShape aTrsfEdges;
for (aUEIter.Initialize(anEdges); aUEIter.More(); aUEIter.Next()) {
const TopoDS_Shape &aUEdge = aUEIter.Value();
aTrsf.Perform(aUEdge);
if (aTrsf.IsDone())
aTrsfEdges.Append(aTrsf.Shape());
}
anEdges.Clear();
anEdges.Append(aTrsfEdges);
}
}
//=======================================================================
//function : SetEdgesForEdge
//purpose :
//=======================================================================
void Unfolding_FaceDataContainer::SetEdgesForEdge
(const TopoDS_Edge &theEdge,
const TopTools_ListOfShape &theUnfoldedEdges)
{
if (myEdgeMap.IsBound(theEdge)) {
TopTools_ListOfShape &anEdges = myEdgeMap.ChangeFind(theEdge);
anEdges = theUnfoldedEdges;
}
}
//=======================================================================
//function : GetEdgesForEdge
//purpose :
//=======================================================================
const TopTools_ListOfShape &Unfolding_FaceDataContainer::GetEdgesForEdge
(const TopoDS_Edge &theEdge) const
{
if (myEdgeMap.IsBound(theEdge)) {
const TopTools_ListOfShape &anEdges = myEdgeMap.Find(theEdge);
return anEdges;
}
static TopTools_ListOfShape anEmptyList;
return anEmptyList;
}

View File

@@ -0,0 +1,101 @@
// File: Unfolding_FaceDataContainer.lxx
// Created: Tue Jul 22 13:12:24 2008
// Author: Sergey KHROMOV
// <skv@dimox>
//=======================================================================
//function : Empty constructor
//purpose :
//=======================================================================
inline Unfolding_FaceDataContainer::Unfolding_FaceDataContainer()
: myDistortionArea(0.),
myCurvature(0.)
{
}
//=======================================================================
//function : GetFace
//purpose :
//=======================================================================
inline const TopoDS_Face &Unfolding_FaceDataContainer::GetFace() const
{
return myFace;
}
//=======================================================================
//function : SetUnfoldedFace
//purpose :
//=======================================================================
inline void Unfolding_FaceDataContainer::SetUnfoldedFace
(const TopoDS_Face &theUnfoldedFace)
{
myUnfoldedFace = theUnfoldedFace;
}
//=======================================================================
//function : GetUnfoldedFace
//purpose :
//=======================================================================
inline const TopoDS_Face &Unfolding_FaceDataContainer::GetUnfoldedFace() const
{
return myUnfoldedFace;
}
//=======================================================================
//function : SetDistortionArea
//purpose :
//=======================================================================
inline void Unfolding_FaceDataContainer::SetDistortionArea
(const Standard_Real theDistortionArea)
{
myDistortionArea = theDistortionArea;
}
//=======================================================================
//function : GetDistortionArea
//purpose :
//=======================================================================
inline Standard_Real Unfolding_FaceDataContainer::GetDistortionArea() const
{
return myDistortionArea;
}
//=======================================================================
//function : SetMaxGaussCurvature
//purpose :
//=======================================================================
inline void Unfolding_FaceDataContainer::SetMaxGaussCurvature
(const Standard_Real theCurvature)
{
myCurvature = theCurvature;
}
//=======================================================================
//function : GetMaxGaussCurvature
//purpose :
//=======================================================================
inline Standard_Real Unfolding_FaceDataContainer::GetMaxGaussCurvature() const
{
return myCurvature;
}
//=======================================================================
//function : Reset
//purpose :
//=======================================================================
inline void Unfolding_FaceDataContainer::Reset()
{
myUnfoldedFace.Nullify();
myDistortionArea = 0.;
myCurvature = 0.;
}

View File

@@ -0,0 +1,32 @@
-- File: Unfolding_FaceDataMapHasher.cdl
-- Created: Fri Sep 19 16:52:05 2008
-- Author: Sergey KHROMOV
-- <skv@kurox>
---Copyright: Matra Datavision 2008
class FaceDataMapHasher from Unfolding
---Purpose: Hash tool, used for generating maps of face data containers.
uses
FaceDataContainer from Unfolding,
Integer from Standard,
Boolean from Standard
is
HashCode(myclass; theKey : FaceDataContainer from Unfolding;
theUpper: Integer from Standard)
---Purpose: Returns a HasCode value for the Key <K> in the
-- range 0..theUpper.
---C++: inline
returns Integer from Standard;
IsEqual(myclass; theKey1, theKey2 : FaceDataContainer from Unfolding)
---Purpose: Returns True when the two keys are the same. Two
-- same keys must have the same hashcode, the
-- contrary is not necessary.
---C++: inline
returns Boolean from Standard;
end;

View File

@@ -0,0 +1,7 @@
// File: Unfolding_FaceDataMapHasher.cxx
// Created: Mon Sep 22 09:01:04 2008
// Author: Sergey KHROMOV
// <skv@kurox>
#include <Unfolding_FaceDataMapHasher.ixx>

View File

@@ -0,0 +1,30 @@
// File: Unfolding_FaceDataMapHasher.lxx
// Created: Mon Sep 22 08:54:51 2008
// Author: Sergey KHROMOV
// <skv@kurox>
//=======================================================================
//function : HashCode
//purpose :
//=======================================================================
inline Standard_Integer Unfolding_FaceDataMapHasher::HashCode
(const Handle(Unfolding_FaceDataContainer) &theKey,
const Standard_Integer theUpper)
{
return (theKey.IsNull()) ? 0 : theKey->GetFace().HashCode(theUpper);
}
//=======================================================================
//function : IsEqual
//purpose :
//=======================================================================
inline Standard_Boolean Unfolding_FaceDataMapHasher::IsEqual
(const Handle(Unfolding_FaceDataContainer) &theKey1,
const Handle(Unfolding_FaceDataContainer) &theKey2)
{
return !theKey1.IsNull() && !theKey2.IsNull() &&
theKey1->GetFace().IsSame(theKey2->GetFace());
}

View File

@@ -0,0 +1,60 @@
-- File: Unfolding_FunctionWithDerivative.cdl
-- Created: Fri Sep 5 17:44:29 2008
-- Author: Mikhail KLOKOV
-- <mkk@kurox>
---Copyright: Open CASCADE 2008
class FunctionWithDerivative from Unfolding inherits FunctionWithDerivative from math
uses
Array1OfXY from TColgp,
Trsf2d from gp,
Dir2d from gp
is
Create (theMaster, theSlave: Array1OfXY from TColgp;
theDir: Dir2d from gp;
theTrsf: Trsf2d from gp)
returns FunctionWithDerivative from Unfolding;
---Purpose:
Value(me: in out; X: Real; F: out Real)
---Purpose: Computes the value <F>of the function for the variable <X>.
-- Returns True if the calculation were successfully done,
-- False otherwise.
returns Boolean
is redefined;
Derivative(me: in out; X: Real; D: out Real)
---Purpose: Computes the derivative <D> of the function
-- for the variable <X>.
-- Returns True if the calculation were successfully done,
-- False otherwise.
returns Boolean
is redefined;
Values(me: in out; X: Real; F, D: out Real)
---Purpose: Computes the value <F> and the derivative <D> of the
-- function for the variable <X>.
-- Returns True if the calculation were successfully done,
-- False otherwise.
returns Boolean
is redefined;
GetStateNumber (me: in out) returns Integer from Standard
is redefined;
Area(me)
returns Real from Standard;
fields
myMasterPolyLine: Array1OfXY from TColgp;
mySlavePolyLine: Array1OfXY from TColgp;
myTrsf: Trsf2d from gp;
myShiftDir: Dir2d from gp;
myShift: Real from Standard;
myArea: Real from Standard;
end FunctionWithDerivative from Unfolding;

View File

@@ -0,0 +1,247 @@
// File: Unfolding_FunctionWithDerivative.cxx
// Created: Fri Sep 5 17:51:58 2008
// Author: Mikhail KLOKOV
// <mkk@kurox>
#include <Unfolding_FunctionWithDerivative.ixx>
static Standard_Boolean ComputeArea(const TColgp_Array1OfXY& theMasterPolyLine,
const TColgp_Array1OfXY& theSlavePolyLine,
const gp_Dir2d& theShiftDir,
const Standard_Real& theShift,
const gp_Trsf2d theTrsf,
Standard_Real& theArea);
static Standard_Boolean ComputeAreaDeriv(const TColgp_Array1OfXY& theMasterPolyLine,
const TColgp_Array1OfXY& theSlavePolyLine,
const gp_Dir2d& theShiftDir,
const Standard_Real& theShift,
const gp_Trsf2d theTrsf,
Standard_Real& theArea,
Standard_Real& theDeriv);
//=============================================================================
// function: Constructor
//=============================================================================
Unfolding_FunctionWithDerivative::Unfolding_FunctionWithDerivative(const TColgp_Array1OfXY& theMaster,
const TColgp_Array1OfXY& theSlave,
const gp_Dir2d& theDir,
const gp_Trsf2d& theTrsf):
myMasterPolyLine(theMaster.Lower(), theMaster.Upper()),
mySlavePolyLine(theSlave.Lower(), theSlave.Upper())
{
myMasterPolyLine.Assign(theMaster);
mySlavePolyLine.Assign(theSlave);
myTrsf = theTrsf;
myShiftDir = theDir;
myShift = 0.;
myArea = 0.;
}
//=============================================================================
// function: Value
//=============================================================================
Standard_Boolean Unfolding_FunctionWithDerivative::Value(const Standard_Real X,Standard_Real& F)
{
myShift = X;
F = 0.;
Standard_Real A = 0.;
Standard_Real D = 0.;
if ( !ComputeAreaDeriv(myMasterPolyLine, mySlavePolyLine, myShiftDir, myShift, myTrsf, A, D) )
return Standard_False;
myArea = A;
gp_XY aP1P2(0, A);
gp_XY vecD(1,D);
Standard_Real modD = vecD.Modulus();
if ( modD < gp::Resolution() ) {
Standard_Real delta = 1.e-7;
if ( !ComputeArea(myMasterPolyLine, mySlavePolyLine, myShiftDir, myShift - delta, myTrsf, A) )
return Standard_False;
gp_XY P1(0,A);
if ( !ComputeArea(myMasterPolyLine, mySlavePolyLine, myShiftDir, myShift + delta, myTrsf, A) )
return Standard_False;
gp_XY P2(0,A);
gp_XY V = P2-P1;
modD = V.Modulus();
if ( modD < gp::Resolution() )
return Standard_False;
}
F = aP1P2 * vecD;
F /= modD;
return Standard_True;
}
//=============================================================================
// function: Derivative
//=============================================================================
Standard_Boolean Unfolding_FunctionWithDerivative::Derivative(const Standard_Real X,Standard_Real& D)
{
Standard_Real F = 0.;
return Values(X,F,D);
}
//=============================================================================
// function: Values
//=============================================================================
Standard_Boolean Unfolding_FunctionWithDerivative::Values(const Standard_Real X,Standard_Real& F,Standard_Real& D)
{
Standard_Real F1 = 0., F2 = 0.;
Standard_Real aDelta = 1.e-05;
if ( fabs(X) > aDelta )
aDelta = fabs(X) * aDelta;
if ( !Value(X + aDelta, F2) )
return Standard_False;
if ( !Value(X, F1) )
return Standard_False;
myShift = X;
F = F1;
D = F2 - F1;
D /= aDelta;
return Standard_True;
}
//=============================================================================
// function: GetStateNumber
//=============================================================================
Standard_Integer Unfolding_FunctionWithDerivative::GetStateNumber()
{
ComputeArea(myMasterPolyLine, mySlavePolyLine, myShiftDir, myShift, myTrsf, myArea);
return 0;
}
//=============================================================================
// function: Area
//=============================================================================
Standard_Real Unfolding_FunctionWithDerivative::Area() const
{
return myArea;
}
//-----------------------------------------------------------------------------
// function: ComputeAreaDeriv
//-----------------------------------------------------------------------------
static Standard_Boolean ComputeAreaDeriv(const TColgp_Array1OfXY& theMasterPolyLine,
const TColgp_Array1OfXY& theSlavePolyLine,
const gp_Dir2d& theShiftDir,
const Standard_Real& theShift,
const gp_Trsf2d theTrsf,
Standard_Real& theArea,
Standard_Real& theDeriv)
{
theArea = 0.;
theDeriv = 0.;
Standard_Real X = theShift;
Standard_Real F1 = 0., F2 = 0.;
if ( !ComputeArea(theMasterPolyLine, theSlavePolyLine, theShiftDir, X, theTrsf, F1) )
return Standard_False;
theArea = F1;
Standard_Real aDelta = 1.e-05;
if ( fabs(X) > aDelta )
aDelta = fabs(X) * aDelta;
if ( !ComputeArea(theMasterPolyLine, theSlavePolyLine, theShiftDir, X + aDelta, theTrsf, F2) )
return Standard_False;
theDeriv = F2 - F1;
theDeriv /= aDelta;
return Standard_True;
}
//-----------------------------------------------------------------------------
// function: ComputeArea
//-----------------------------------------------------------------------------
static Standard_Boolean ComputeArea(const TColgp_Array1OfXY& theMasterPolyLine,
const TColgp_Array1OfXY& theSlavePolyLine,
const gp_Dir2d& theShiftDir,
const Standard_Real& theShift,
const gp_Trsf2d theTrsf,
Standard_Real& theArea)
{
if ( ( theMasterPolyLine.Length() < 2 ) || ( theSlavePolyLine.Length() < 2 ) ||
( theSlavePolyLine.Length() != theMasterPolyLine.Length() ) )
return Standard_False;
theArea = 0.;
gp_Vec2d aTranslation( theShiftDir.XY() * theShift );
gp_Trsf2d aTransTrsf;
aTransTrsf.SetTranslation( aTranslation );
gp_Trsf2d aTrans;
aTrans = aTransTrsf * theTrsf;
//
TColgp_Array1OfXY aTransformedSlave(theSlavePolyLine.Lower(), theSlavePolyLine.Upper());
Standard_Integer i = 0;
for ( i = aTransformedSlave.Lower(); i <= aTransformedSlave.Upper(); i++ ) {
gp_Pnt2d aP( theSlavePolyLine.Value( i ) );
aP.Transform( aTrans );
aTransformedSlave.SetValue( i, aP.XY() );
}
//
// compute area
// This method assumes that the polylines shape is similar
// if the shape is completely different, the compute area will be wrong.
// But it will grow, that can be considered as a condition of distortion.
// So, the method can be acceptable.
gp_XY aFirstPoint = aTransformedSlave( aTransformedSlave.Lower() );
aFirstPoint += theMasterPolyLine( theMasterPolyLine.Lower() );
aFirstPoint *= 0.5;
gp_XY aLastPoint = aTransformedSlave( aTransformedSlave.Upper() );
aLastPoint += theMasterPolyLine( theMasterPolyLine.Upper() );
aLastPoint *= 0.5;
Standard_Integer nIndexDif = theMasterPolyLine.Lower() - aTransformedSlave.Lower();
gp_XY aP1 = aFirstPoint;
gp_XY aP3 = aFirstPoint;
for ( i = theMasterPolyLine.Lower() + 1; i <= theMasterPolyLine.Upper(); i++ ) {
gp_XY aP2 = theMasterPolyLine(i);
gp_XY aP4 = aTransformedSlave(i-nIndexDif);
if ( i == theMasterPolyLine.Upper() ) {
aP2 = aLastPoint;
aP4 = aLastPoint;
}
gp_XY aP1P4 = aP4 - aP1;
gp_XY aP1P2 = aP2 - aP1;
gp_XY aP1P3 = aP3 - aP1;
Standard_Real aprod1 = aP1P4 ^ aP1P3;
Standard_Real aprod2 = aP1P4 ^ aP1P2;
if ( aprod1 * aprod2 <= 0. ) {
theArea += 0.5 * ( fabs( aprod1 ) + fabs( aprod2 ) );
}
else {
gp_XY aP3P2 = aP2 - aP3;
gp_XY aP3P4 = aP4 - aP3;
gp_XY aP3P1 = -aP1P3;
Standard_Real asum = 0.5 * ( fabs( aprod1 ) + fabs( aprod2 ) );
aprod1 = aP3P2 ^ aP3P4;
aprod2 = aP3P2 ^ aP3P1;
if ( aprod1 * aprod2 <= 0. ) {
theArea += 0.5 * ( fabs( aprod1 ) + fabs( aprod2 ) );
}
else {
asum += 0.5 * ( fabs( aprod1 ) + fabs( aprod2 ) );
asum *= 0.5;
theArea += asum;
}
}
aP1 = aP2;
aP3 = aP4;
}
return Standard_True;
}

View File

@@ -0,0 +1,82 @@
-- File: Unfolding_Point.cdl
-- Created: Mon Jul 28 14:56:12 2008
-- Author: Sergey KHROMOV
-- <skv@dimox>
---Copyright: Matra Datavision 2008
class Point from Unfolding
---Purpose: This class represents a data container for a point. It contains
-- a point on a surface, its U and V parameters on a surface,
-- corresponding point on an unfolding plane.
uses
XY from gp,
XYZ from gp,
Real from Standard
is
Create
---Purpose: Empty constructor.
---C++: inline
returns Point from Unfolding;
SetPointOnSurface(me: in out; thePOnSurface: XYZ from gp);
---Purpose: Sets the point on a surface.
---C++: inline
GetPointOnSurface(me)
---Purpose: Returns the point on a surface.
---C++: return const &
---C++: inline
returns XYZ from gp;
SetParameters(me: in out; theU: Real from Standard;
theV: Real from Standard);
---Purpose: Sets the U and V parameters of the point on a surface.
---C++: inline
GetParameters(me; theU: out Real from Standard;
theV: out Real from Standard);
---Purpose: Returns the U and V parameters of the point on a surface.
---C++: inline
GetU(me)
---Purpose: Returns the U parameter of the point on a surface.
---C++: inline
returns Real from Standard;
GetV(me)
---Purpose: Returns the V parameter of the point on a surface.
---C++: inline
returns Real from Standard;
SetAngle(me: in out; theAngle: Real from Standard);
---Purpose: Sets the angle between DU and DV directions.
---C++: inline
GetAngle(me)
---Purpose: Returns the angle between DU and DV directions.
---C++: inline
returns Real from Standard;
SetPointOnPlane(me: in out; thePOnPlane: XY from gp);
---Purpose: Sets the point on an unfolding plane.
---C++: inline
GetPointOnPlane(me)
---Purpose: Returns the point on an unfolding plane.
---C++: return const &
---C++: inline
returns XY from gp;
fields
myPoint2d : XY from gp;
myPOnSurface : XYZ from gp;
myPOnPlane : XY from gp;
myAngle : Real from Standard;
end;

View File

@@ -0,0 +1,8 @@
// File: Unfolding_Point.cxx
// Created: Mon Jul 28 15:27:34 2008
// Author: Sergey KHROMOV
// <skv@dimox>
#include <Unfolding_Point.hxx>

View File

@@ -0,0 +1,116 @@
// File: Unfolding_Point.lxx
// Created: Mon Jul 28 15:18:15 2008
// Author: Sergey KHROMOV
// <skv@dimox>
//=======================================================================
//function : Empty constructor
//purpose :
//=======================================================================
inline Unfolding_Point::Unfolding_Point()
: myAngle(-1.)
{
}
//=======================================================================
//function : SetPointOnSurface
//purpose :
//=======================================================================
inline void Unfolding_Point::SetPointOnSurface(const gp_XYZ &thePOnSurface)
{
myPOnSurface = thePOnSurface;
}
//=======================================================================
//function : GetPointOnSurface
//purpose :
//=======================================================================
inline const gp_XYZ &Unfolding_Point::GetPointOnSurface() const
{
return myPOnSurface;
}
//=======================================================================
//function : SetParameters
//purpose :
//=======================================================================
inline void Unfolding_Point::SetParameters(const Standard_Real theU,
const Standard_Real theV)
{
myPoint2d.SetCoord(theU, theV);
}
//=======================================================================
//function : GetParameters
//purpose :
//=======================================================================
inline void Unfolding_Point::GetParameters(Standard_Real &theU,
Standard_Real &theV) const
{
myPoint2d.Coord(theU, theV);
}
//=======================================================================
//function : GetU
//purpose :
//=======================================================================
inline Standard_Real Unfolding_Point::GetU() const
{
return myPoint2d.X();
}
//=======================================================================
//function : GetV
//purpose :
//=======================================================================
inline Standard_Real Unfolding_Point::GetV() const
{
return myPoint2d.Y();
}
//=======================================================================
//function : GetAngle
//purpose :
//=======================================================================
inline void Unfolding_Point::SetAngle(const Standard_Real theAngle)
{
myAngle = theAngle;
}
//=======================================================================
//function : GetAngle
//purpose :
//=======================================================================
inline Standard_Real Unfolding_Point::GetAngle() const
{
return myAngle;
}
//=======================================================================
//function : SetPointOnPlane
//purpose :
//=======================================================================
inline void Unfolding_Point::SetPointOnPlane(const gp_XY &thePOnPlane)
{
myPOnPlane = thePOnPlane;
}
//=======================================================================
//function : GetPointOnPlane
//purpose :
//=======================================================================
inline const gp_XY &Unfolding_Point::GetPointOnPlane() const
{
return myPOnPlane;
}

View File

@@ -0,0 +1,167 @@
-- File: Unfolding_Shell.cdl
-- Created: Tue Sep 9 16:56:09 2008
-- Author: Mikhail KLOKOV
-- <mkk@kurox>
---Copyright: Open CASCADE 2008
class Shell from Unfolding
---Purpose: This class is used to perform unfolding of a shell onto a plane.
-- To perform this operation it is necessary to initialize the
-- object by a shell to be unfolded, a plane and a tolerance for
-- operation. Then to call the method Perform. The result planar
-- shell can be obtained using the method GetResult. Error status
-- can be obtained by the method ErrorStatus.
uses
ErrorStatus from Unfolding,
Shell from TopoDS,
Face from TopoDS,
ListOfShape from TopTools,
Pln from gp,
Real from Standard,
IndexedMapOfFaceDataContainer from Unfolding,
FaceDataContainer from Unfolding
is
Create
---Purpose: Empty constructor
returns Shell from Unfolding;
Create (theShell : Shell from TopoDS;
thePlane : Pln from gp;
theContourTolerance: Real from Standard;
theCurvatureTolerance: Real from Standard = 0.001;
theDeflection: Real from Standard = 0.001)
---Purpose: Constructor. Initializes the object with the shell, the plane and
-- the tolerances for operation.
returns Shell from Unfolding;
SetShell (me: in out; theShell: Shell from TopoDS);
---Purpose: Sets the face.
---C++: inline
GetShell (me)
---Purpose: Returns the shell.
---C++: inline
---C++: return const &
returns Shell from TopoDS;
SetPlane (me: in out; thePlane: Pln from gp);
---Purpose: Sets the plane.
---C++: inline
GetPlane (me)
---Purpose: Returns the plane.
---C++: inline
---C++: return const &
returns Pln from gp;
SetCurvatureTolerance (me: in out; theTolerance: Real from Standard);
---Purpose: Sets the tolerance for the operation.
---C++: inline
GetCurvatureTolerance (me)
---Purpose: Returns the tolerance for the operation.
---C++: inline
returns Real from Standard;
SetContourTolerance (me: in out; theTolerance: Real from Standard);
---Purpose: Sets the tolerance for the operation.
---C++: inline
GetContourTolerance (me)
---Purpose: Returns the tolerance for the operation.
---C++: inline
returns Real from Standard;
SetDeflection (me: in out; theDeflection: Real from Standard);
---Purpose: Sets the tolerance for the operation.
---C++: inline
GetDeflection (me)
---Purpose: Returns the tolerance for the operation.
---C++: inline
returns Real from Standard;
Perform (me: in out)
---Purpose: Performs computation of the unfolded surface. It returns
-- Standard_True if the operation succeeds otherwise returns
-- Standard_False. It is possible to get the error status of
-- the performed operation using the method ErrorStatus().
returns Boolean from Standard;
ErrorStatus (me)
---Purpose: Returns error status of the operation. The error status can have
-- one of the following values:
-- - Unfolding_Done: operation is succeeded;
-- - Unfolding_NotDone: the method Perform() is not called yet;
-- - Unfolding_Failure: the operation is failed;
-- - Unfolding_InvalidSurface: the surface cannot be unfolded
-- without distortion;
-- - Unfolding_InvalidInput: invalid input for the operation;
-- - Unfolding_InvalidShape: can be returned by
-- Unfolding::ToShape method;
-- - Unfolding_ComplexShape: can be returned by
-- Unfolding::ToShape method;
---C++: inline
returns ErrorStatus from Unfolding;
GetResult (me)
---Purpose: Returns the result of the operation. If the operation is failed,
-- it returns a null shape.
---C++: inline
---C++: return const &
returns Face from TopoDS;
GetAreaError(me)
---Purpose: Returns the area cumulated during primitive patches mergin.
-- It shows computed distortion.
---C++: inline
returns Real from Standard;
GetMaxGaussCurvature(me)
---Purpose: Returns the gauss curvature computed in the mesh points.
---C++: inline
returns Real from Standard;
--protected
Reset(me: in out)
---Purpose: Resets data to the initial state.
---C++: inline
is protected;
--private
ComputeTransformed(me: in out; theResult: in out ListOfShape from TopTools)
returns Boolean from Standard
is private;
MoveFace2ToFace1(me: in out; theFaceData1 : FaceDataContainer from Unfolding;
theFaceData2 : FaceDataContainer from Unfolding;
theCommonEdges: ListOfShape from TopTools;
theIsFixed : Boolean from Standard)
---Purpose: Perform transformation of unfolded face2 to glue with unfolded
-- face1. If theIsFixed is Standard_True, the face 2 is not
-- transformed only estimations of distortions are performed.
returns Boolean from Standard
is private;
fields
myShell : Shell from TopoDS;
myPlane : Pln from gp;
myTolContour : Real from Standard;
myTolCurvature : Real from Standard;
myDeflection : Real from Standard;
myMapFaceData : IndexedMapOfFaceDataContainer from Unfolding;
myResult : Face from TopoDS;
myErrorStatus : ErrorStatus from Unfolding;
myDistortionArea : Real from Standard;
myCurvature : Real from Standard;
end Shell from Unfolding;

View File

@@ -0,0 +1,777 @@
// File: Unfolding_Shell.cxx
// Created: Tue Sep 9 17:14:33 2008
// Author: Mikhail KLOKOV
// <mkk@kurox>
#include <Unfolding_Shell.ixx>
#include <Unfolding.hxx>
#include <Unfolding_FunctionWithDerivative.hxx>
#include <Unfolding_Surface.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <Geom_Plane.hxx>
#include <math_FunctionRoot.hxx>
#include <math_NewtonFunctionRoot.hxx>
#include <ShapeAnalysis_FreeBoundData.hxx>
#include <ShapeAnalysis_FreeBoundsProperties.hxx>
#include <TColgp_Array1OfXY.hxx>
#include <TColgp_HArray1OfXY.hxx>
#include <TColgp_SequenceOfXY.hxx>
#include <TColStd_ListOfInteger.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_MapOfShape.hxx>
#include <BRepCheck_Analyzer.hxx>
static Standard_Boolean CombineCurves(const TColgp_Array1OfXY& theMasterPolyLine,
const TColgp_Array1OfXY& theSlavePolyLine,
const Standard_Boolean IsFixed,
const Standard_Real theConfTolerance,
const Standard_Real theAreaTolerance,
gp_Trsf2d& theTransformation,
Standard_Real& theDistortionArea);
// ==============================================================================
// function: GetCommonEdges
// purpose : This function returns the list of common edges of two faces.
// ==============================================================================
static void GetCommonEdges(const TopoDS_Face &theFace1,
const TopoDS_Face &theFace2,
TopTools_ListOfShape &theCommonEdges)
{
TopTools_IndexedMapOfShape aMapEdges1;
TopExp_Explorer anExp2(theFace2, TopAbs_EDGE);
TopExp::MapShapes(theFace1, TopAbs_EDGE, aMapEdges1);
theCommonEdges.Clear();
for (; anExp2.More(); anExp2.Next()) {
const TopoDS_Shape &anEdge2 = anExp2.Current();
if (aMapEdges1.Contains(anEdge2))
theCommonEdges.Append(anEdge2);
}
}
// ==============================================================================
// function: GetWires
// purpose : This function returns a list of wires edges composed from theEdges.
// ==============================================================================
static Standard_Boolean GetWires(const TopTools_ListOfShape &theEdges,
TopTools_ListOfShape &theWires)
{
TopTools_ListIteratorOfListOfShape anEdgeIter(theEdges);
TopTools_DataMapOfShapeListOfShape aMapVE;
TopExp_Explorer anExp;
TopTools_MapOfShape aMapUsed;
for (; anEdgeIter.More(); anEdgeIter.Next()) {
const TopoDS_Shape &anEdge = anEdgeIter.Value();
if (!aMapUsed.Add(anEdge) || BRep_Tool::Degenerated(TopoDS::Edge(anEdge)))
continue;
for (anExp.Init(anEdge, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
const TopoDS_Shape &aVertex = anExp.Current();
if (!aMapVE.IsBound(aVertex)) {
TopTools_ListOfShape aList;
aMapVE.Bind(aVertex, aList);
}
TopTools_ListOfShape &aListAncEdges = aMapVE.ChangeFind(aVertex);
aListAncEdges.Append(anEdge);
}
}
// Construct wires as chains of edges.
Standard_Boolean isToTreat = Standard_True;
TopoDS_Vertex aFirstVtx;
TopoDS_Edge aCurEdge;
TopoDS_Vertex aV[2];
BRep_Builder aBuilder;
for(;;) {
isToTreat = Standard_False;
// Get the bounding vertex, i.e. the vertex that contains only one edge in
// the list of ancestors.
TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aMapIter(aMapVE);
for (; aMapIter.More(); aMapIter.Next()) {
const TopTools_ListOfShape &anEdges = aMapIter.Value();
if (anEdges.Extent() == 1) {
isToTreat = Standard_True;
break;
}
}
if (!isToTreat) {
// Get a closed loop.
for (aMapIter.Initialize(aMapVE); aMapIter.More(); aMapIter.Next()) {
const TopTools_ListOfShape &anEdges = aMapIter.Value();
if (anEdges.Extent() == 1) {
isToTreat = Standard_True;
break;
}
}
}
// Stop treatment if there is no more edges.
if (!isToTreat)
break;
// Treat the list of edges starting from the current iterator.
TopoDS_Wire aWire;
aBuilder.MakeWire(aWire);
aFirstVtx = TopoDS::Vertex(aMapIter.Key());
while (!aFirstVtx.IsNull()) {
const TopTools_ListOfShape &anEdges = aMapVE.ChangeFind(aFirstVtx);
aCurEdge = TopoDS::Edge(anEdges.First());
TopExp::Vertices(aCurEdge, aV[0], aV[1], Standard_True);
if (aFirstVtx.IsSame(aV[1])) {
aV[1] = aV[0];
aV[0] = aFirstVtx;
aCurEdge.Reverse();
}
aBuilder.Add(aWire, aCurEdge);
TopTools_ListOfShape &anEdges1 = aMapVE.ChangeFind(aV[0]);
TopTools_ListOfShape &anEdges2 = aMapVE.ChangeFind(aV[1]);
// Remove the current edge from aMapVE.
anEdges1.RemoveFirst();
if (anEdges1.IsEmpty())
aMapVE.UnBind(aV[0]);
if (anEdges2.IsEmpty() || anEdges2.Extent() > 2)
return Standard_False;
if (aCurEdge.IsSame(anEdges2.First())) {
// Remove first element.
anEdges2.RemoveFirst();
} else if (aCurEdge.IsSame(anEdges2.Last())) {
// Remove last element.
TopTools_ListIteratorOfListOfShape anEdgeIt(anEdges2);
anEdgeIt.Next();
anEdges2.Remove(anEdgeIt);
} else {
return Standard_False;
}
if (anEdges2.IsEmpty()) {
aMapVE.UnBind(aV[1]);
aFirstVtx.Nullify();
} else {
aFirstVtx = aV[1];
}
}
theWires.Append(aWire);
}
return Standard_True;
}
// ==============================================================================
// function: Constructor
// ==============================================================================
Unfolding_Shell::Unfolding_Shell()
: myTolContour(0.001),
myTolCurvature(0.001),
myDeflection(0.001),
myDistortionArea(0.),
myCurvature(0.)
{
Reset();
}
// ==============================================================================
// function: Constructor
// ==============================================================================
Unfolding_Shell::Unfolding_Shell(const TopoDS_Shell& theShell,
const gp_Pln& thePlane,
const Standard_Real theContourTolerance,
const Standard_Real theCurvatureTolerance,
const Standard_Real theDeflection)
: myShell(theShell),
myPlane(thePlane),
myTolContour(theContourTolerance),
myTolCurvature(theCurvatureTolerance),
myDeflection(theDeflection),
myDistortionArea(0.),
myCurvature(0.)
{
Reset();
}
// ==============================================================================
// function: Perform
// ==============================================================================
Standard_Boolean Unfolding_Shell::Perform()
{
// Check if the operation is already performed and there is nothing to do.
if (myErrorStatus != Unfolding_NotDone)
return (myErrorStatus == Unfolding_Done);
// Check input data validity.
if (myShell.IsNull() ||
( myTolContour <= RealEpsilon() ) ||
( myTolCurvature <= RealEpsilon() ) ||
( myDeflection <= RealEpsilon() ) ) {
myErrorStatus = Unfolding_InvalidInput;
return Standard_False;
}
// Compute number of samples for each edge of the shell.
TopTools_DataMapOfShapeInteger aMapEdgeNbSamples;
TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
Standard_Integer i;
Standard_Integer aNbEdges;
TopExp::MapShapesAndAncestors(myShell, TopAbs_EDGE, TopAbs_FACE, aMapEF);
aNbEdges = aMapEF.Extent();
for (i = 1; i <= aNbEdges; i++) {
TopoDS_Edge anEdge = TopoDS::Edge(aMapEF.FindKey(i));
const TopTools_ListOfShape &aFaces = aMapEF.FindFromIndex(i);
Standard_Integer aNbPoints = Unfolding::NbSamples(anEdge, aFaces,
myTolContour);
aMapEdgeNbSamples.Bind(anEdge, aNbPoints);
}
// Perform unfolding of each face.
TopTools_ListOfShape aList2Sew;
myDistortionArea = 0.;
myCurvature = 0.;
TopExp_Explorer anExp( myShell, TopAbs_FACE );
Standard_Boolean isFirstReversed = Standard_False;
for ( ; anExp.More(); anExp.Next() ) {
TopoDS_Face aFaceOriginal = TopoDS::Face( anExp.Current() );
TopoDS_Face aFace = aFaceOriginal;
aFace.Orientation( TopAbs_FORWARD );
Unfolding_Surface anUnfoldFace(aFace, myPlane, myTolContour,
myTolCurvature, myDeflection);
Standard_Boolean isDone =
anUnfoldFace.Perform(aMapEdgeNbSamples);
Handle(Unfolding_FaceDataContainer) aFaceData = anUnfoldFace.GetDataContainer();
// Keep the original orientation of unfolding data container.
aFaceData->SetFace(aFaceOriginal);
if ( myCurvature < aFaceData->GetMaxGaussCurvature() )
myCurvature = aFaceData->GetMaxGaussCurvature();
myDistortionArea += aFaceData->GetDistortionArea();
if ( !isDone ) {
myErrorStatus = anUnfoldFace.ErrorStatus();
return Standard_False;
}
if ( myMapFaceData.IsEmpty() ) {
isFirstReversed = ( aFaceOriginal.Orientation() == TopAbs_REVERSED );
}
TopoDS_Face aNewFace = aFaceData->GetUnfoldedFace();
Standard_Boolean toReverse = ( aFaceOriginal.Orientation() == TopAbs_REVERSED );
if ( isFirstReversed )
toReverse = !toReverse;
gp_Trsf aTrsfPln;
if ( toReverse ) {
// Take into account the faces of different orientation are unfolded
// as mirror compared to the first unfolded face representation
aTrsfPln.SetMirror( gp_Ax1( myPlane.Location(), myPlane.Position().XDirection() ) );
aFaceData->ApplyTrsf(aTrsfPln);
}
myMapFaceData.Add(aFaceData);
}
//
if ( !ComputeTransformed( aList2Sew ) ) {
return Standard_False;
}
//
BRep_Builder aBuilder;
TopoDS_Compound aCompound;
TopTools_ListIteratorOfListOfShape anIt( aList2Sew );
aBuilder.MakeCompound(aCompound);
for ( ; anIt.More(); anIt.Next() )
aBuilder.Add(aCompound, anIt.Value());
Unfolding_ErrorStatus aStatus;
TopoDS_Shell aShell = Unfolding::ToShell(aCompound,
myTolContour, aStatus);
if (aShell.IsNull()) {
switch (aStatus) {
case Unfolding_ComplexShape:
myErrorStatus = Unfolding_ComplexShape;
break;
case Unfolding_InvalidShape:
myErrorStatus = Unfolding_InvalidShape;
break;
default:
myErrorStatus = Unfolding_Failure;
break;
}
return Standard_False;
}
ShapeAnalysis_FreeBoundsProperties aFreeBoundAlgo(aShell);
if ( !aFreeBoundAlgo.Perform() ) {
myErrorStatus = Unfolding_Failure;
return Standard_False;
}
Handle(ShapeAnalysis_HSequenceOfFreeBounds) aSeqWire;
aSeqWire = aFreeBoundAlgo.ClosedFreeBounds();
BRepBuilderAPI_MakeFace aFaceMaker(myPlane);
if ( !aSeqWire.IsNull() ) {
for ( Standard_Integer w = 1; w <= aSeqWire->Length(); w++ ) {
aFaceMaker.Add( aSeqWire->Value(w)->FreeBound() );
}
}
myResult = aFaceMaker.Face();
#ifdef DEB
cout << "Checking the result..." << endl;
#endif
BRepCheck_Analyzer aChecker( myResult, Standard_True );
if ( !aChecker.IsValid() ) {
myErrorStatus = Unfolding_ComplexShape;
return Standard_False;
}
return Standard_True;
}
// ==============================================================================
// function: ComputeTransformed
// ==============================================================================
Standard_Boolean Unfolding_Shell::ComputeTransformed(TopTools_ListOfShape& theResult)
{
theResult.Clear();
// If the map of face data is empty, nothing to do.
if (myMapFaceData.IsEmpty())
return Standard_True;
TopTools_MapOfShape aMapTreated;
TColStd_MapOfInteger aMapTreatedIndices;
TopTools_IndexedDataMapOfShapeListOfShape aMapEF;
Standard_Integer i;
Standard_Integer aNbFaces = myMapFaceData.Extent();
TColStd_ListOfInteger aListToTreat;
Handle(Unfolding_FaceDataContainer) aDummyFaceData;
aDummyFaceData = new Unfolding_FaceDataContainer;
TopExp::MapShapesAndAncestors( myShell, TopAbs_EDGE, TopAbs_FACE, aMapEF );
for (i = 1; i <= aNbFaces; i++) {
// Skip index already treated.
if (aMapTreatedIndices.Contains(i))
continue;
aListToTreat.Append(i);
while (!aListToTreat.IsEmpty()) {
Standard_Integer anIndex = aListToTreat.First();
if (!aMapTreatedIndices.Add(anIndex))
continue;
aListToTreat.RemoveFirst();
const Handle(Unfolding_FaceDataContainer) &aFaceData =
myMapFaceData.FindKey(anIndex);
const TopoDS_Face &aFace =
aFaceData->GetFace();
aMapTreated.Add(aFace);
TopExp_Explorer anEdgeExp(aFace, TopAbs_EDGE);
for ( ; anEdgeExp.More(); anEdgeExp.Next() ) {
const TopoDS_Shape &anEdge = anEdgeExp.Current();
if (!aMapTreated.Add(anEdge) || !aMapEF.Contains(anEdge)) {
// This edge is already treated or it is absent in aMapEF. Skip it.
continue;
}
// Treat faces share the edge anEdge with the face aFace.
const TopTools_ListOfShape &aFaces = aMapEF.FindFromKey(anEdge);
TopTools_ListIteratorOfListOfShape aFaceIter(aFaces);
for (; aFaceIter.More(); aFaceIter.Next()) {
const TopoDS_Shape &aNeighborFace = aFaceIter.Value();
// Skip aFace
if (aFace.IsSame(aNeighborFace))
continue;
aDummyFaceData->SetFace(TopoDS::Face(aNeighborFace));
Standard_Boolean isFixed = !aMapTreated.Add(aNeighborFace);
Standard_Integer aNeighborIndex = myMapFaceData.FindIndex(aDummyFaceData);
if (aNeighborIndex == 0) {
myErrorStatus = Unfolding_Failure;
return Standard_False; // This is an invalid case.
}
const Handle(Unfolding_FaceDataContainer) &aNeighborFaceData =
myMapFaceData.FindKey(aNeighborIndex);
TopTools_ListOfShape aCommonEdges;
GetCommonEdges(aFace, aNeighborFaceData->GetFace(), aCommonEdges);
if (!MoveFace2ToFace1(aFaceData, aNeighborFaceData,
aCommonEdges, isFixed))
return Standard_False;
// Add common edge to the map of treated shapes.
TopTools_ListIteratorOfListOfShape anEdgeIter(aCommonEdges);
for (; anEdgeIter.More(); anEdgeIter.Next())
aMapTreated.Add(anEdgeIter.Value());
if (!isFixed)
aListToTreat.Append(aNeighborIndex);
}
}
theResult.Append(aFaceData->GetUnfoldedFace());
}
}
return Standard_True;
}
// ==============================================================================
// function: MoveFace2ToFace1
// ==============================================================================
Standard_Boolean Unfolding_Shell::MoveFace2ToFace1
(const Handle(Unfolding_FaceDataContainer) &theFaceData1,
const Handle(Unfolding_FaceDataContainer) &theFaceData2,
const TopTools_ListOfShape &theCommonEdges,
const Standard_Boolean theIsFixed)
{
TopTools_ListOfShape aWires;
if (!GetWires(theCommonEdges, aWires)) {
myErrorStatus = Unfolding_Failure;
return Standard_False;
}
// Get a wire with the greatest distance between first and last vertices.
TopoDS_Wire aRefWire;
TopoDS_Wire aWire;
TopTools_ListIteratorOfListOfShape anIter(aWires);
Standard_Real aMaxDist = -1;
Standard_Real aDist;
TopoDS_Vertex aV[2];
for (; anIter.More(); anIter.Next()) {
aWire = TopoDS::Wire(anIter.Value());
TopExp::Vertices(aWire, aV[0], aV[1]);
gp_Pnt aP1 = BRep_Tool::Pnt(aV[0]);
gp_Pnt aP2 = BRep_Tool::Pnt(aV[1]);
aDist = aP1.Distance(aP2);
if (aDist > aMaxDist) {
aMaxDist = aDist;
aRefWire = aWire;
}
}
if (aRefWire.IsNull()) {
myErrorStatus = Unfolding_Failure;
return Standard_False;
}
// Compute points.
Standard_Boolean isReversedOn1 = Standard_False;
Standard_Boolean isReversedOn2 = Standard_False;
TopExp_Explorer anExp(aRefWire, TopAbs_EDGE);
if (anExp.More()) {
TopoDS_Edge aFirstEdge = TopoDS::Edge(anExp.Current());
TopoDS_Face aFace1 = theFaceData1->GetFace();
TopoDS_Face aFace2 = theFaceData2->GetFace();
TopExp_Explorer aFaceExp(aFace1, TopAbs_EDGE);
for (; aFaceExp.More(); aFaceExp.Next()) {
const TopoDS_Shape &anEdgeOnF1 = aFaceExp.Current();
if (aFirstEdge.IsSame(anEdgeOnF1)) {
if (aFirstEdge.Orientation() != anEdgeOnF1.Orientation())
isReversedOn1 = Standard_True;
break;
}
}
// If aFirstEdge is not found on the face1. It is not possible by construction.
// Return with error status.
if (!aFaceExp.More()) {
myErrorStatus = Unfolding_Failure;
return Standard_False;
}
if (aFace1.Orientation() == aFace2.Orientation())
isReversedOn2 = !isReversedOn1;
else
isReversedOn2 = isReversedOn1;
}
// Collect points.
TopoDS_Shape aFace1 = theFaceData1->GetUnfoldedFace();
TopoDS_Shape aFace2 = theFaceData2->GetUnfoldedFace();
TColgp_SequenceOfXY aMasterPoints;
TColgp_SequenceOfXY aSlavePoints;
gp_Pnt2d aUV[2];
Handle(Geom_Surface) aSurface = new Geom_Plane(myPlane);
TopLoc_Location aLoc;
for (; anExp.More(); anExp.Next()) {
TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
const TopTools_ListOfShape &anUnfld1 = theFaceData1->GetEdgesForEdge(anEdge);
const TopTools_ListOfShape &anUnfld2 = theFaceData2->GetEdgesForEdge(anEdge);
// Fill aMasterPoints.
for (anIter.Initialize(anUnfld1); anIter.More(); anIter.Next()) {
TopoDS_Edge anUnfoldEdge = TopoDS::Edge(anIter.Value());
if (isReversedOn1)
BRep_Tool::UVPoints(anUnfoldEdge, aSurface, aLoc, aUV[1], aUV[0]);
else
BRep_Tool::UVPoints(anUnfoldEdge, aSurface, aLoc, aUV[0], aUV[1]);
// Add the first point if the collection is empty.
if (aMasterPoints.IsEmpty())
aMasterPoints.Append(aUV[0].XY());
// Add the last point.
if (isReversedOn1)
aMasterPoints.Prepend(aUV[1].XY());
else
aMasterPoints.Append(aUV[1].XY());
}
// Fill aSlavePoints.
for (anIter.Initialize(anUnfld2); anIter.More(); anIter.Next()) {
TopoDS_Edge anUnfoldEdge = TopoDS::Edge(anIter.Value());
if (isReversedOn2)
BRep_Tool::UVPoints(anUnfoldEdge, aSurface, aLoc, aUV[1], aUV[0]);
else
BRep_Tool::UVPoints(anUnfoldEdge, aSurface, aLoc, aUV[0], aUV[1]);
// Add the first point if the collection is empty.
if (aSlavePoints.IsEmpty())
aSlavePoints.Append(aUV[0].XY());
// Add the last point.
if (isReversedOn2)
aSlavePoints.Prepend(aUV[1].XY());
else
aSlavePoints.Append(aUV[1].XY());
}
}
// Construct array of points.
Handle(TColgp_HArray1OfXY) aMasterPolyLine;
Handle(TColgp_HArray1OfXY) aSlavePolyLine;
Standard_Integer i = 0;
aMasterPolyLine = new TColgp_HArray1OfXY( 1, aMasterPoints.Length() );
aSlavePolyLine = new TColgp_HArray1OfXY( 1, aSlavePoints.Length() );
for ( i = aMasterPolyLine->Lower(); i <= aMasterPolyLine->Upper(); i++ )
aMasterPolyLine->SetValue( i, aMasterPoints(i) );
for ( i = aSlavePolyLine->Lower(); i <= aSlavePolyLine->Upper(); i++ )
aSlavePolyLine->SetValue( i, aSlavePoints(i) );
// Compute transformation
gp_Trsf2d aTransformation2d;
Standard_Real aDistortionArea;
if ( !CombineCurves(aMasterPolyLine->Array1(), aSlavePolyLine->Array1(),
theIsFixed, myTolContour, myTolContour*myTolContour,
aTransformation2d, aDistortionArea) ) {
myDistortionArea += aDistortionArea;
myErrorStatus = Unfolding_InvalidSurface;
return Standard_False;
}
myDistortionArea += aDistortionArea;
// Trasform face
if (!theIsFixed) {
gp_Trsf aTrsf2dTo3d( aTransformation2d );
gp_Trsf aTrsfPln1, aTrsfPln2;
gp_Ax3 anAx3( gp_Pnt(0,0,0), gp_Dir(0,0,1), gp_Dir(1,0,0));
aTrsfPln1.SetDisplacement( myPlane.Position(), anAx3 );
aTrsfPln2.SetDisplacement( anAx3, myPlane.Position() );
gp_Trsf aTransformation = aTrsf2dTo3d * aTrsfPln1;
aTransformation = aTrsfPln2 * aTransformation;
theFaceData2->ApplyTrsf(aTransformation);
}
return Standard_True;
}
//-----------------------------------------------------------------------
//function : CombineCurves
//purpose :
//-----------------------------------------------------------------------
static Standard_Boolean CombineCurves(const TColgp_Array1OfXY& theMasterPolyLine,
const TColgp_Array1OfXY& theSlavePolyLine,
const Standard_Boolean IsFixed,
const Standard_Real theConfTolerance,
const Standard_Real theAreaTolerance,
gp_Trsf2d& theTransformation,
Standard_Real& theDistortionArea)
{
theDistortionArea = 0.;
if ( ( theMasterPolyLine.Length() < 2 ) || ( theSlavePolyLine.Length() < 2 ) )
return Standard_False;
gp_XY aPMasterFirst = theMasterPolyLine.Value(theMasterPolyLine.Lower());
gp_XY aPMasterLast = theMasterPolyLine.Value(theMasterPolyLine.Upper());
gp_XY aPSlaveFirst = theSlavePolyLine.Value(theSlavePolyLine.Lower());
gp_XY aPSlaveLast = theSlavePolyLine.Value(theSlavePolyLine.Upper());
if (aPMasterFirst.IsEqual(aPMasterLast, theConfTolerance) ||
aPSlaveFirst.IsEqual(aPSlaveLast, theConfTolerance)) {
// One of polylines is closed. Get the points previous to the last ones.
aPMasterLast = theMasterPolyLine.Value(theMasterPolyLine.Upper() - 1);
aPSlaveLast = theSlavePolyLine.Value(theSlavePolyLine.Upper() - 1);
if (aPMasterFirst.IsEqual(aPMasterLast, theConfTolerance) ||
aPSlaveFirst.IsEqual(aPSlaveLast, theConfTolerance))
return Standard_False;
}
Standard_Real aRotation = 0.;
gp_XY aTranslation;
gp_Vec2d aLineDir1(aPMasterLast - aPMasterFirst);
gp_Vec2d aLineDir2(aPSlaveLast - aPSlaveFirst);
aTranslation = aPMasterFirst - aPSlaveFirst;
Standard_Real aLen1 = aLineDir1.Magnitude();
Standard_Real aLen2 = aLineDir2.Magnitude();
Standard_Real aShift = ( aLen2 - aLen1 ) * 0.5;
if ( aLen1 > gp::Resolution() ) {
aTranslation = aTranslation - aLineDir1.XY() * (aShift / aLen1);
if ( aLen2 > gp::Resolution() )
aRotation = aLineDir1.Angle( aLineDir2 );
}
// compute base transformation
gp_Trsf2d aRotTrsf;
aRotTrsf.SetRotation(aPSlaveFirst, -aRotation);
gp_Trsf2d aTransTrsf;
aTransTrsf.SetTranslation( gp_Vec2d(aTranslation) );
theTransformation = aTransTrsf * aRotTrsf;
//
// Compute transformation of shift to minimize the area of
// poly-lines difference
gp_Dir2d aDir(1,0);
if ( aLen1 > gp::Resolution() )
aDir = gp_Dir2d( gp_XY(-aLineDir1.Y(), aLineDir1.X() ) ) ;
Unfolding_FunctionWithDerivative aFunc( theMasterPolyLine, theSlavePolyLine, aDir, theTransformation );
if (IsFixed) {
Standard_Real aVal;
aFunc.Value(0, aVal);
theDistortionArea = aFunc.Area();
return Standard_True;
} else {
Standard_Real aBoundary = aShift * 20.;
const Standard_Real aTolX = 1.e-05;
if ( fabs(aBoundary) < aTolX * 2. ) {
Standard_Real aVal = 0.;
aFunc.Value(0, aVal);
theDistortionArea = aFunc.Area();
return Standard_True;
}
const Standard_Real aTolF = ( theAreaTolerance < 1.e-06 ) ? 1.e-06 : theAreaTolerance;
math_NewtonFunctionRoot R( aFunc, 0., aTolX, aTolF, -aBoundary, aBoundary, 10 );
if ( R.IsDone() ) {
gp_Trsf2d aTransTrsfAdd;
aTransTrsfAdd.SetTranslation( gp_Vec2d(aDir.XY() * R.Root() ) );
theTransformation = aTransTrsfAdd * theTransformation;
theDistortionArea = aFunc.Area();
}
else {
math_FunctionRoot R2( aFunc, 0., aTolX, -aBoundary, aBoundary );
if ( R2.IsDone() ) {
gp_Trsf2d aTransTrsfAdd;
aTransTrsfAdd.SetTranslation( gp_Vec2d(aDir.XY() * R2.Root() ) );
theTransformation = aTransTrsfAdd * theTransformation;
theDistortionArea = aFunc.Area();
}
}
}
return Standard_True;
}

View File

@@ -0,0 +1,99 @@
// File: Unfolding_Shell.lxx
// Created: Tue Sep 9 17:14:56 2008
// Author: Mikhail KLOKOV
// <mkk@kurox>
inline void Unfolding_Shell::SetShell(const TopoDS_Shell& theShell)
{
myShell = theShell;
}
inline const TopoDS_Shell& Unfolding_Shell::GetShell() const
{
return myShell;
}
inline void Unfolding_Shell::SetPlane(const gp_Pln& thePlane)
{
myPlane = thePlane;
}
inline const gp_Pln& Unfolding_Shell::GetPlane() const
{
return myPlane;
}
inline void Unfolding_Shell::SetCurvatureTolerance(const Standard_Real theTolerance)
{
myTolCurvature = theTolerance;
}
inline Standard_Real Unfolding_Shell::GetCurvatureTolerance() const
{
return myTolCurvature;
}
inline void Unfolding_Shell::SetContourTolerance(const Standard_Real theTolerance)
{
myTolContour = theTolerance;
}
inline Standard_Real Unfolding_Shell::GetContourTolerance() const
{
return myTolContour;
}
inline void Unfolding_Shell::SetDeflection(const Standard_Real theDeflection)
{
myDeflection = theDeflection;
}
inline Standard_Real Unfolding_Shell::GetDeflection() const
{
return myDeflection;
}
inline Unfolding_ErrorStatus Unfolding_Shell::ErrorStatus() const
{
return myErrorStatus;
}
inline const TopoDS_Face& Unfolding_Shell::GetResult() const
{
return myResult;
}
inline Standard_Real Unfolding_Shell::GetAreaError() const
{
return myDistortionArea;
}
inline Standard_Real Unfolding_Shell::GetMaxGaussCurvature() const
{
return myCurvature;
}
inline void Unfolding_Shell::Reset()
{
myDistortionArea = 0.;
myCurvature = 0.;
myErrorStatus = Unfolding_NotDone;
myMapFaceData.Clear();
myResult.Nullify();
}

View File

@@ -0,0 +1,200 @@
-- File: Unfolding_Surface.cdl
-- Created: Tue Jul 22 12:50:10 2008
-- Author: Sergey KHROMOV
-- <skv@dimox>
---Copyright: Open CASCADE 2008
class Surface from Unfolding
---Purpose: This class is used to perform unfolding of a face onto a plane.
-- To perform this operation it is necessary to initialize the
-- object by a face to be unfolded, a plane and a tolerance for
-- operation. Then to call the method Perform. The result planar
-- face can be obtained using the method GetResult. Error status
-- can be obtained by the method ErrorStatus.
uses
ErrorStatus from Unfolding,
HArray2OfPoint from Unfolding,
FaceDataContainer from Unfolding,
Face from TopoDS,
Wire from TopoDS,
Edge from TopoDS,
Vertex from TopoDS,
ListOfShape from TopTools,
Pln from gp,
XY from gp,
Real from Standard,
DataMapOfShapeInteger from TopTools
is
Create
---Purpose: Empty constructor
---C++: inline
returns Surface from Unfolding;
Create (theFace : Face from TopoDS;
thePlane : Pln from gp;
theContourTolerance : Real from Standard;
theCurvatureTolerance: Real from Standard = 0.001;
theDeflection : Real from Standard = 0.001)
---Purpose: Constructor. Initializes the object with the face, the plane and
-- the tolerance for operation.
returns Surface from Unfolding;
SetFace (me: in out; theFace: Face from TopoDS);
---Purpose: Sets the face.
---C++: inline
GetFace (me)
---Purpose: Returns the face.
---C++: inline
---C++: return const &
returns Face from TopoDS;
SetPlane (me: in out; thePlane: Pln from gp);
---Purpose: Sets the plane.
---C++: inline
GetPlane (me)
---Purpose: Returns the plane.
---C++: inline
---C++: return const &
returns Pln from gp;
SetCurvatureTolerance (me: in out; theTolerance: Real from Standard);
---Purpose: Sets the tolerance for the operation.
---C++: inline
GetCurvatureTolerance (me)
---Purpose: Returns the tolerance for the operation.
---C++: inline
returns Real from Standard;
SetContourTolerance (me: in out; theTolerance: Real from Standard);
---Purpose: Sets the tolerance for the operation.
---C++: inline
GetContourTolerance (me)
---Purpose: Returns the tolerance for the operation.
---C++: inline
returns Real from Standard;
SetDeflection (me: in out; theDeflection: Real from Standard);
---Purpose: Sets the tolerance for the operation.
---C++: inline
GetDeflection (me)
---Purpose: Returns the tolerance for the operation.
---C++: inline
returns Real from Standard;
Perform (me: in out; theMapEdgeNbSamples: DataMapOfShapeInteger from TopTools)
---Purpose: Performs computation of the unfolded surface. It returns
-- Standard_True if the operation succeeds otherwise returns
-- Standard_False. It is possible to get the error status of
-- the performed operation using the method ErrorStatus().
-- theMapEdgeNbSamples is the map of edges as keys and
-- number of samples for this edge as item. It is required
-- for predefined sampling of edges of a face. If an edge is
-- absent in this map its sampling is automatically computed.
-- This feature is used to get same sampling for shared edges
-- on different faces.
returns Boolean from Standard;
ErrorStatus (me)
---Purpose: Returns error status of the operation. The error status can have
-- one of the following values:
-- - Unfolding_Done: operation is succeeded;
-- - Unfolding_NotDone: the method Perform() is not called yet;
-- - Unfolding_Failure: the operation is failed;
-- - Unfolding_InvalidSurface: the surface cannot be unfolded
-- without distortion;
-- - Unfolding_InvalidInput: invalid input for the operation.
---C++: inline
returns ErrorStatus from Unfolding;
GetDataContainer(me)
---Purpose: Returns data container. That stores all results of the operation.
---C++: inline
returns FaceDataContainer from Unfolding;
--protected
Reset(me: in out)
---Purpose: Resets data to the initial state.
---C++: inline
is protected;
--private
InitGrid(me: in out)
---Purpose: Initializes the grid on surface. Computes a rectangular grid in
-- the parametric space of the face and computes the corresponding
-- 3d points on the surface.
returns Boolean from Standard
is private;
NbPoints(me; theUMin : Real from Standard;
theUMax : Real from Standard;
theVMin : Real from Standard;
theVMax : Real from Standard;
theNbPointsU: out Integer from Standard;
theNbPointsV: out Integer from Standard)
---Purpose: Computes and returns the numbers of sampling points
-- for U and V directions.
is private;
Unfolding(me: in out)
---Purpose: Performs unfolding of the grid of points onto the plane. Returns
-- Standard_True in case of success and Standard_False otherwise.
-- Initializes the error status of the operation.
returns Boolean from Standard
is private;
BuildPlanarFace(me: in out;
theMapEdgeNbSamples: DataMapOfShapeInteger from TopTools)
---Purpose: Constructs and returns a planar face.
returns Boolean from Standard
is private;
BuildPlanarWire(me: in out;
theWire : Wire from TopoDS;
theMapEdgeNbSamples: DataMapOfShapeInteger from TopTools;
thePlanarWire : out Wire from TopoDS)
---Purpose: Constructs and returns planar unfolded wire from original one.
returns Boolean from Standard
is private;
UnfoldEdge(me;
theEdge : Edge from TopoDS;
theStartVtx : Vertex from TopoDS;
theEndVtx : Vertex from TopoDS;
theMapEdgeNbSamples: DataMapOfShapeInteger from TopTools;
theStartPnt : in out XY from gp;
theEndPnt : out XY from gp;
thePlnEdges : out ListOfShape from TopTools)
---Purpose: Constructs and returns a set of planar unfolded edges
-- from theEdge.
returns Boolean from Standard
is private;
ComputePointOnPlane(me; thePoint : XY from gp;
theEdgeTol : Real from Standard;
thePointOnPlane: out XY from gp)
---Purpose: Computes and returns a point on plane that corresponds
-- to a point on a surface.
returns Boolean from Standard
is private;
fields
myDataContainer : FaceDataContainer from Unfolding;
myPlane : Pln from gp;
myTolContour : Real from Standard;
myTolCurvature : Real from Standard;
myDeflection : Real from Standard;
myGrid : HArray2OfPoint from Unfolding;
myErrorStatus : ErrorStatus from Unfolding;
end;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,132 @@
// File: Unfolding_Surface.lxx
// Created: Tue Jul 22 16:13:39 2008
// Author: Sergey KHROMOV
// <skv@dimox>
#include <Unfolding_FaceDataContainer.hxx>
//=======================================================================
//function : SetFace
//purpose :
//=======================================================================
inline void Unfolding_Surface::SetFace (const TopoDS_Face &theFace)
{
myDataContainer->SetFace(theFace);
Reset();
}
//=======================================================================
//function : GetFace
//purpose :
//=======================================================================
inline const TopoDS_Face &Unfolding_Surface::GetFace () const
{
return myDataContainer->GetFace();
}
//=======================================================================
//function : SetPlane
//purpose :
//=======================================================================
inline void Unfolding_Surface::SetPlane (const gp_Pln &thePlane)
{
myPlane = thePlane;
Reset();
}
//=======================================================================
//function : GetPlane
//purpose :
//=======================================================================
inline const gp_Pln &Unfolding_Surface::GetPlane () const
{
return myPlane;
}
//=======================================================================
//function : SetTolerance
//purpose :
//=======================================================================
inline void Unfolding_Surface::SetContourTolerance (const Standard_Real theTolerance)
{
myTolContour = theTolerance;
Reset();
}
//=======================================================================
//function : GetTolerance
//purpose :
//=======================================================================
inline Standard_Real Unfolding_Surface::GetContourTolerance () const
{
return myTolContour;
}
inline void Unfolding_Surface::SetCurvatureTolerance(const Standard_Real theTolerance)
{
myTolCurvature = theTolerance;
Reset();
}
inline Standard_Real Unfolding_Surface::GetCurvatureTolerance() const
{
return myTolCurvature;
}
inline void Unfolding_Surface::SetDeflection(const Standard_Real theDeflection)
{
myDeflection = theDeflection;
Reset();
}
inline Standard_Real Unfolding_Surface::GetDeflection() const
{
return myDeflection;
}
//=======================================================================
//function : ErrorStatus
//purpose :
//=======================================================================
inline Unfolding_ErrorStatus Unfolding_Surface::ErrorStatus () const
{
return myErrorStatus;
}
//=======================================================================
//function : GetDataContainer
//purpose :
//=======================================================================
inline Handle(Unfolding_FaceDataContainer)
Unfolding_Surface::GetDataContainer() const
{
return myDataContainer;
}
//=======================================================================
//function : Reset
//purpose :
//=======================================================================
inline void Unfolding_Surface::Reset()
{
myDataContainer->Reset();
myErrorStatus = Unfolding_NotDone;
if (!myGrid.IsNull())
myGrid.Nullify();
}

View File

@@ -0,0 +1,24 @@
-- File: UnfoldingTest.cdl
-- Created: Tue Jul 22 18:15:41 2008
-- Author: Sergey KHROMOV
-- <skv@dimox>
---Copyright: Matra Datavision 2008
package UnfoldingTest
---Purpose: This package defines a set of Draw commands for testing of
-- functionality of the package Unfolding.
uses
Draw
is
Commands(theDI: in out Interpretor from Draw);
---Purpose: Adds Draw commands to the draw interpretor.
Factory(theDI: out Interpretor from Draw);
---Purpose: Plugin entry point function.
end UnfoldingTest;

View File

@@ -0,0 +1,272 @@
// File: UnfoldingTest.cxx
// Created: Tue Jul 22 18:35:23 2008
// Author: Sergey KHROMOV
// <skv@dimox>
#include <UnfoldingTest.hxx>
#include <Draw.hxx>
#include <Draw_PluginMacro.hxx>
#include <Draw_Interpretor.hxx>
#include <TopoDS_Shape.hxx>
#include <DBRep.hxx>
#include <TopoDS_Shell.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS.hxx>
#include <Geom_Surface.hxx>
#include <DrawTrSurf.hxx>
#include <Geom_Plane.hxx>
#include <Unfolding_Surface.hxx>
#include <Unfolding_Shell.hxx>
#include <Unfolding.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
//=======================================================================
//function : dumpError
//purpose :
//=======================================================================
static void dumpError (Draw_Interpretor &di,
const Standard_Integer theStatus)
{
di << " Status: ";
switch (theStatus) {
case Unfolding_Done:
di << "Done";
break;
case Unfolding_NotDone:
di << "NotDone";
break;
case Unfolding_Failure:
di << "Failure";
break;
case Unfolding_InvalidSurface:
di << "InvalidSurface";
break;
case Unfolding_InvalidInput:
di << "InvalidInput";
break;
case Unfolding_InvalidShape:
di << "InvalidShape";
break;
case Unfolding_ComplexShape:
di << "ComplexShape";
break;
default:
di << "Unknown";
break;
}
di << " \n";
}
//=======================================================================
//function : unfolding
//purpose :
//=======================================================================
static Standard_Integer unfolding (Draw_Interpretor &di,
Standard_Integer n, const char** a)
{
if (n < 4 || n > 7) {
di << "Usage: " << a[0] << " result face|shell plane [tol_contour] [tol_curvature] [deflection]" << "\n";
return 1;
}
// Get a shape from a[2].
TopoDS_Shape aShape = DBRep::Get(a[2]);
if (aShape.IsNull()) {
di << a[2] << " is not a shape!" << "\n";
return 1;
}
// Check if the shape is a face.
if (aShape.ShapeType() != TopAbs_FACE &&
aShape.ShapeType() != TopAbs_SHELL) {
di << a[2] << " is not a face or shell!" << "\n";
return 1;
}
TopoDS_Shell aShell;
TopoDS_Face aFace;
if (aShape.ShapeType() == TopAbs_FACE) {
aFace = TopoDS::Face( aShape );
if (aFace.IsNull()) {
di << a[2] << " is not a face!" << "\n";
return 1;
}
}
else {
aShell = TopoDS::Shell( aShape );
}
// Get a surface from a[3].
Handle(Geom_Surface) aSurface = DrawTrSurf::GetSurface(a[3]);
if (aSurface.IsNull()) {
di << a[3] << " is not a surface!" << "\n";
return 1;
}
// Cast the surface to a plane.
Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast(aSurface);
if (aPlane.IsNull()) {
di << a[3] << " is not a plane!" << "\n";
return 1;
}
// Get the tolerance value.
Standard_Real aTolContour = 0.001;
if (n >= 5) {
aTolContour = Draw::Atof(a[4]);
} else {
di << "tolerance value is not provided. The default value " << aTolContour << " is used" << "\n";
}
// Get the curvature tolerance value.
Standard_Real aTolCurv = 0.001;
if (n >= 6) {
aTolCurv = Draw::Atof(a[5]);
} else {
di << "curvature value is not provided. The default value " << aTolCurv << " is used" << "\n";
}
// Get the curvature tolerance value.
Standard_Real aDefl = 0.001;
if (n == 7) {
aDefl = Draw::Atof(a[6]);
} else {
di << "deflection value is not provided. The default value " << aDefl << " is used" << "\n";
}
// Initialization of the unfolding algorithm
Standard_Boolean isOK = Standard_False;
TopoDS_Shape aResult;
Standard_Integer aErrorStatus = 0;
if ( !aFace.IsNull() ) {
TopTools_DataMapOfShapeInteger anEmptyMap;
Unfolding_Surface anUnfold(aFace, aPlane->Pln(), aTolContour, aTolCurv, aDefl);
isOK = anUnfold.Perform(anEmptyMap);
Handle(Unfolding_FaceDataContainer) aData = anUnfold.GetDataContainer();
di << "Gauss curvature =" << aData->GetMaxGaussCurvature() << "\n";
di << "Area of error =" << aData->GetDistortionArea() << "\n";
if ( isOK )
aResult = aData->GetUnfoldedFace();
aErrorStatus = anUnfold.ErrorStatus();
}
else if ( !aShell.IsNull() ) {
Unfolding_Shell anUnfold(aShell, aPlane->Pln(), aTolContour, aTolCurv, aDefl);
isOK = anUnfold.Perform();
di << "Gauss curvature =" << anUnfold.GetMaxGaussCurvature() << "\n";
di << "Area of error =" << anUnfold.GetAreaError() << "\n";
if ( isOK )
aResult = anUnfold.GetResult();
aErrorStatus = anUnfold.ErrorStatus();
}
if (isOK) {
DBRep::Set(a[1], aResult);
} else {
di << "Unfolding failure!" << "\n";
dumpError(di, aErrorStatus);
return 1;
}
return 0;
}
//=======================================================================
//function : toshell
//purpose :
//=======================================================================
static Standard_Integer toshell (Draw_Interpretor &di,
Standard_Integer n, const char** a)
{
if (n != 3 && n != 4) {
di << "Usage: " << a[0] << " result shape [tolerance]" << "\n";;
return 1;
}
// Get a shape from a[2].
TopoDS_Shape aShape = DBRep::Get(a[2]);
if (aShape.IsNull()) {
di << a[2] << " is not a shape!" << "\n";
return 1;
}
// Get the tolerance value.
Standard_Real aTolerance = 1.e-6;
if (n == 4) {
aTolerance = Draw::Atof(a[3]);
} else {
di << "tolerance value is not provided. The default value " << aTolerance << " is used" << "\n";
}
Unfolding_ErrorStatus aStatus;
TopoDS_Shell aResult = Unfolding::ToShell(aShape, aTolerance, aStatus);
if (aResult.IsNull()) {
di << "toshell failure!" << "\n";
dumpError(di, aStatus);
return 1;
}
DBRep::Set(a[1], aResult);
return 0;
}
//=======================================================================
//function : Commands
//purpose :
//=======================================================================
void UnfoldingTest::Commands(Draw_Interpretor &theDI)
{
static Standard_Boolean done = Standard_False;
if (done)
return;
done = Standard_True;
// Chapter's name
const char* group = "Unfolding commands";
theDI.Add("unfolding","unfolding result face|shell plane [tol_contour] [tol_curvature] [deflection]",
__FILE__, unfolding, group);
theDI.Add("toshell","toshell result shape [tolerance]",
__FILE__, toshell, group);
}
//=======================================================================
//function : Factory
//purpose :
//=======================================================================
void UnfoldingTest::Factory(Draw_Interpretor &theDI)
{
UnfoldingTest::Commands(theDI);
#ifdef DEB
theDI << "Draw Plugin : Unfolding commands are loaded" << "\n";
#endif
}
// Declare entry point PLUGINFACTORY
DPLUGIN(UnfoldingTest)

View File

@@ -13,7 +13,6 @@
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <OpenGl_GlCore20.hxx>
#include <AIS_Shape.hxx>
#include <AIS_InteractiveObject.hxx>
@@ -2117,8 +2116,8 @@ static LRESULT WINAPI ViewerWindowProc( HWND hwnd,
}
}
break;
case WM_MOUSEWHEEL:
#if _MSC_VER >= 1500
case WM_MOUSEWHEEL:
{
int aDelta = GET_WHEEL_DELTA_WPARAM (wParam);
if (wParam & MK_CONTROL)
@@ -2134,12 +2133,13 @@ static LRESULT WINAPI ViewerWindowProc( HWND hwnd,
}
}
}
else
else
{
aView->Zoom (0, 0, aDelta / 40, aDelta / 40);
}
break;
}
#endif
case WM_MOUSEMOVE:
{