Changes for bug 0020673.

This commit is contained in:
skl 2010-02-25 14:12:14 +00:00
parent 8e8618994c
commit 3ba64429c6
16 changed files with 208 additions and 34 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -6,22 +6,34 @@ To generate a \b Filling in the <b>Main Menu</b> select <b>New Entity - > Genera
To create a curving face using several edges you need to define the
following parameters:
\n <b>Edges Compound</b> - the list of edges used for creation of the
surface;
\n \b Minimum and <b>Maximum Degree</b> of equation of the resulting BSpline or Besier curves describing the surface;
\n <b>Input Compound</b> - the list of edges/wires used for creation
of the surface. Before perform filling algorithm each wire from
compound is converted to one edge created on BSpline curve built using
curves from all edges from wire.
\n \b Minimum and <b>Maximum Degree</b> of equation of the resulting
BSpline or Besier curves describing the surface;
\n \b Tolerance for \b 2D and for \b 3D - minimum distance between the
created surface and the reference edge;
\n <b>Number of
Iterations</b> - defines the maximum number of iterations. The iterations are repeated until the required tolerance is reached. So, a greater number of iterations allows producing a better surface.
\n <b>Approximation</b> - if checked, BSpline curves are generated in the process of surface construction (using GeomAPI_PointsToBSplineSurface functionality). By default the surface is created using Besier curves. The usage of <b>Approximation</b> makes the algorithm work slower, but allows building the
surface for rather complex cases.
Iterations</b> - defines the maximum number of iterations. The
iterations are repeated until the required tolerance is reached. So, a
greater number of iterations allows producing a better surface.
\n <b>Use orientation</b> - if checked, orientation of edges are used:
if edge is reversed curve from this edge is reversed before using in
filling algorithm.
\n <b>Approximation</b> - if checked, BSpline curves are generated in
the process of surface construction (using
GeomAPI_PointsToBSplineSurface functionality). By default the surface
is created using Besier curves. The usage of <b>Approximation</b>
makes the algorithm work slower, but allows building the surface for
rather complex cases.
\n The \b Result of the operation will be a GEOM_Object (face).
\n <b>TUI Command:</b> <em>geompy.MakeFilling(Edges, MinDegree, MaxDegree, Tol2D, Tol3D, NbIter)</em>
\n <b>Arguments:</b> Name + 1 List of edges + 6 Parameters
\n <b>Arguments:</b> Name + 1 List of edges + 7 Parameters
(Min. degree, Max. degree, Number of iterations, 2D tolerance, 3D
tolerance, Number of iterations, Appro).
tolerance, Number of iterations, Use orientation, Approximation).
\image html filling.png

View File

@ -1185,7 +1185,8 @@ module GEOM
GEOM_Object MakeFilling (in GEOM_Object theShape,
in long theMinDeg, in long theMaxDeg,
in double theTol2D, in double theTol3D,
in long theNbIter, in boolean theApprox);
in long theNbIter, in boolean theUseOri,
in boolean theApprox);
/*!
* Create a shell or solid passing through set of sections.Sections should be wires,edges or vertices.

View File

@ -200,7 +200,8 @@ module GEOM
GEOM_Object MakeFilling (in GEOM_Object theShape,
in long theMinDeg, in long theMaxDeg,
in double theTol2D, in double theTol3D,
in long theNbIter, in boolean theApprox) ;
in long theNbIter, in boolean theUseOri,
in boolean theApprox) ;
GEOM_Object MakeThruSections(in ListOfGO theSeqSections,
in boolean theModeSolid,
in double thePreci,

View File

@ -685,7 +685,7 @@ Please, select face, shell or solid and try again</translation>
</message>
<message>
<source>GEOM_FILLING_COMPOUND</source>
<translation>Edges compound</translation>
<translation>Input compound</translation>
</message>
<message>
<source>GEOM_FILLING_MAX_DEG</source>
@ -3731,6 +3731,10 @@ Please, select face, shell or solid and try again</translation>
<source>GEOM_FILLING_APPROX</source>
<translation>Approximation</translation>
</message>
<message>
<source>GEOM_FILLING_USEORI</source>
<translation>Use orientation</translation>
</message>
<message>
<source>GEOM_WRN_NO_APPROPRIATE_SELECTION</source>
<translation>No appropriate objects selected</translation>

View File

@ -29,15 +29,23 @@
#include <BRep_Tool.hxx>
#include <BRepAlgo.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRep_Builder.hxx>
#include <TopAbs.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopExp_Explorer.hxx>
#include <Geom_Curve.hxx>
#include <Geom_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Ellipse.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BSplineSurface.hxx>
#include <GeomFill_Line.hxx>
#include <GeomFill_AppSurf.hxx>
@ -50,6 +58,13 @@
#include <ShapeFix_Face.hxx>
#include <GeomAPI_PointsToBSplineSurface.hxx>
#include <Geom_BSplineCurve.hxx>
#include <GeomAPI_PointsToBSpline.hxx>
#include <TColgp_SequenceOfPnt.hxx>
#include <TColgp_Array1OfPnt.hxx>
//#include <BRepTools.hxx>
//=======================================================================
//function : GetID
@ -95,6 +110,7 @@ Standard_Integer GEOMImpl_FillingDriver::Execute(TFunction_Logbook& log) const
Standard_Real tol2d = IF.GetTol3D();
Standard_Integer nbiter = IF.GetNbIter();
Standard_Boolean isApprox = IF.GetApprox();
Standard_Boolean isUseOri = IF.GetUseOri();
if (mindeg > maxdeg) {
Standard_RangeError::Raise("Minimal degree can not be more than maximal degree");
@ -106,12 +122,103 @@ Standard_Integer GEOMImpl_FillingDriver::Execute(TFunction_Logbook& log) const
Standard_Real First, Last;
Handle(Geom_Curve) C;
TopoDS_Compound aComp;
BRep_Builder B;
B.MakeCompound(aComp);
TopoDS_Iterator It (aShape);
for (; It.More(); It.Next()) {
Scurrent = It.Value();
if (Scurrent.ShapeType() != TopAbs_EDGE)
Standard_ConstructionError::Raise("The argument compound must contain only edges");
if (Scurrent.ShapeType() != TopAbs_EDGE) {
Handle(Geom_BSplineCurve) newC;
if (Scurrent.ShapeType() == TopAbs_WIRE) {
TColgp_SequenceOfPnt PntSeq;
// collect points
for (Ex.Init(Scurrent, TopAbs_EDGE); Ex.More(); Ex.Next()) {
TopoDS_Edge E = TopoDS::Edge(Ex.Current());
if (BRep_Tool::Degenerated(E)) continue;
C = BRep_Tool::Curve(E, First, Last);
if( E.Orientation() == TopAbs_REVERSED ) {
C->Reverse();
}
Handle(Geom_TrimmedCurve) tc = Handle(Geom_TrimmedCurve)::DownCast(C);
while( !tc.IsNull() ) {
C = tc->BasisCurve();
tc = Handle(Geom_TrimmedCurve)::DownCast(C);
}
int nbp = 10;
if( C->IsKind(STANDARD_TYPE(Geom_Line)) ) {
nbp = 4;
}
else if( C->IsKind(STANDARD_TYPE(Geom_Circle)) ||
C->IsKind(STANDARD_TYPE(Geom_Ellipse)) ) {
nbp = (int)25*fabs(Last-First)/(2*PI);
}
else if( C->IsKind(STANDARD_TYPE(Geom_BezierCurve)) ) {
Handle(Geom_BezierCurve) C3d = Handle(Geom_BezierCurve)::DownCast(C);
nbp = C3d->NbPoles();
}
else if( C->IsKind(STANDARD_TYPE(Geom_BSplineCurve)) ) {
Handle(Geom_BSplineCurve) C3d = Handle(Geom_BSplineCurve)::DownCast(C);
nbp = C3d->NbPoles();
}
else {
}
if( nbp<4 ) nbp = 4;
double dp = (Last-First)/(nbp-1);
for(int i=1; i<nbp; i++) {
gp_Pnt P;
C->D0(First+dp*(i-1),P);
PntSeq.Append(P);
}
}
// add last point
gp_Pnt P;
C->D0(Last,P);
PntSeq.Append(P);
// create BSpline
if(PntSeq.Length()>1) {
TColgp_Array1OfPnt Pnts(1,PntSeq.Length());
// check orientation of wire
if( Scurrent.Orientation() == TopAbs_REVERSED ) {
for(int i=1; i<=PntSeq.Length(); i++) {
Pnts.SetValue(PntSeq.Length()-i+1,PntSeq.Value(i));
}
}
else {
for(int i=1; i<=PntSeq.Length(); i++) {
Pnts.SetValue(i,PntSeq.Value(i));
}
}
GeomAPI_PointsToBSpline PTB(Pnts);
newC = Handle(Geom_BSplineCurve)::DownCast(PTB.Curve());
// set periodic flag if curve is closed
//if( newC->IsClosed() ) {
// newC->SetPeriodic();
//}
// create edge
double fp = newC->FirstParameter();
double lp = newC->FirstParameter();
gp_Pnt PF,PL;
newC->D0(fp,PF);
newC->D0(lp,PL);
TopoDS_Vertex VF,VL;
B.MakeVertex(VF,PF,1.e-7);
B.MakeVertex(VL,PL,1.e-7);
TopoDS_Edge newE;
B.MakeEdge(newE,newC,1.e-7);
B.Add(newE,VF);
B.Add(newE,VL.Reversed());
Scurrent = newE;
}
}
if(newC.IsNull()) {
Standard_ConstructionError::Raise("The argument compound must contain only edges");
}
}
B.Add(aComp,Scurrent);
}
aShape = aComp;
if (!isApprox) {
// make filling as in old version of SALOME (before 4.1.1)
@ -122,11 +229,15 @@ Standard_Integer GEOMImpl_FillingDriver::Execute(TFunction_Logbook& log) const
if (Scurrent.IsNull() || Scurrent.ShapeType() != TopAbs_EDGE) return 0;
if (BRep_Tool::Degenerated(TopoDS::Edge(Scurrent))) continue;
C = BRep_Tool::Curve(TopoDS::Edge(Scurrent), First, Last);
if (Scurrent.Orientation() == TopAbs_REVERSED)
// Mantis isuue 0020659: consider the orientation of the edges
C = new Geom_TrimmedCurve(C, Last, First);
else
C = new Geom_TrimmedCurve(C, First, Last);
//if (Scurrent.Orientation() == TopAbs_REVERSED)
// // Mantis isuue 0020659: consider the orientation of the edges
// C = new Geom_TrimmedCurve(C, Last, First);
//else
// C = new Geom_TrimmedCurve(C, First, Last);
C = new Geom_TrimmedCurve(C, First, Last);
if( isUseOri && Scurrent.Orientation() == TopAbs_REVERSED ) {
C->Reverse();
}
Section.AddCurve(C);
i++;
}

View File

@ -1453,7 +1453,8 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeRevolutionAxisAngle2Ways
//=============================================================================
Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFilling
(Handle(GEOM_Object) theShape, int theMinDeg, int theMaxDeg,
double theTol2D, double theTol3D, int theNbIter, bool isApprox)
double theTol2D, double theTol3D, int theNbIter,
bool isUseOri, bool isApprox)
{
SetErrorCode(KO);
@ -1482,6 +1483,7 @@ Handle(GEOM_Object) GEOMImpl_I3DPrimOperations::MakeFilling
aFI.SetTol3D(theTol3D);
aFI.SetNbIter(theNbIter);
aFI.SetApprox(isApprox);
aFI.SetUseOri(isUseOri);
//Compute the Solid value
try {

View File

@ -100,7 +100,8 @@ class GEOMImpl_I3DPrimOperations : public GEOM_IOperations {
Standard_EXPORT Handle(GEOM_Object) MakeFilling (Handle(GEOM_Object) theShape,
int theMinDeg, int theMaxDeg,
double theTol2D, double theTol3D,
int theNbIter, bool isApprox);
int theNbIter, bool isUseOri,
bool isApprox);
Standard_EXPORT Handle(GEOM_Object) MakeThruSections
(const Handle(TColStd_HSequenceOfTransient)& theSeqSections,

View File

@ -30,6 +30,7 @@
#define FILL_ARG_SHAPE 5
#define FILL_ARG_NBITER 6
#define FILL_ARG_APPROX 7
#define FILL_ARG_USEORI 8
class GEOMImpl_IFilling
{
@ -52,6 +53,9 @@ class GEOMImpl_IFilling
void SetApprox(bool theApprox) { _func->SetInteger(FILL_ARG_APPROX, theApprox); }
bool GetApprox() { return _func->GetInteger(FILL_ARG_APPROX); }
void SetUseOri(bool theUseOri) { _func->SetInteger(FILL_ARG_USEORI, theUseOri); }
bool GetUseOri() { return _func->GetInteger(FILL_ARG_USEORI); }
void SetShape(Handle(GEOM_Function) theShape) { _func->SetReference(FILL_ARG_SHAPE, theShape); }
Handle(GEOM_Function) GetShape() { return _func->GetReference(FILL_ARG_SHAPE); }

View File

@ -710,6 +710,7 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakeFilling(GEOM::GEOM_Object_pt
CORBA::Double theTol2D,
CORBA::Double theTol3D,
CORBA::Long theNbIter,
CORBA::Boolean theUseOri,
CORBA::Boolean theApprox)
{
GEOM::GEOM_Object_var aGEOMObject;
@ -724,7 +725,8 @@ GEOM::GEOM_Object_ptr GEOM_I3DPrimOperations_i::MakeFilling(GEOM::GEOM_Object_pt
//Create the Solid
Handle(GEOM_Object) anObject = GetOperations()->MakeFilling
(aShape, theMinDeg, theMaxDeg, theTol2D, theTol3D, theNbIter, theApprox);
(aShape, theMinDeg, theMaxDeg, theTol2D, theTol3D, theNbIter,
theUseOri, theApprox);
if (!GetOperations()->IsDone() || anObject.IsNull())
return aGEOMObject._retn();

View File

@ -134,7 +134,11 @@ class GEOM_I_EXPORT GEOM_I3DPrimOperations_i :
GEOM::GEOM_Object_ptr theAxis,
CORBA::Double theAngle);
GEOM::GEOM_Object_ptr MakeFilling(GEOM::GEOM_Object_ptr theShape, CORBA::Long theMinDeg, CORBA::Long theMaxDeg, CORBA::Double theTol2D, CORBA::Double theTol3D, CORBA::Long theNbIter, CORBA::Boolean theApprox);
GEOM::GEOM_Object_ptr MakeFilling(GEOM::GEOM_Object_ptr theShape,
CORBA::Long theMinDeg, CORBA::Long theMaxDeg,
CORBA::Double theTol2D, CORBA::Double theTol3D,
CORBA::Long theNbIter, CORBA::Boolean theUseOri,
CORBA::Boolean theApprox);
GEOM::GEOM_Object_ptr MakeThruSections(const GEOM::ListOfGO& theSeqSections,
CORBA::Boolean theModeSolid,

View File

@ -1242,14 +1242,20 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeRevolutionAxisAngle2Ways (GEOM::GEOM_Ob
// MakeFilling:
//=============================================================================
GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeFilling (GEOM::GEOM_Object_ptr theShape,
CORBA::Long theMinDeg, CORBA::Long theMaxDeg,
CORBA::Double theTol2D, CORBA::Double theTol3D,
CORBA::Long theNbIter, CORBA::Boolean theApprox)
CORBA::Long theMinDeg,
CORBA::Long theMaxDeg,
CORBA::Double theTol2D,
CORBA::Double theTol3D,
CORBA::Long theNbIter,
CORBA::Boolean theUseOri,
CORBA::Boolean theApprox)
{
beginService( " GEOM_Superv_i::MakeFilling" );
MESSAGE("GEOM_Superv_i::MakeFilling");
get3DPrimOp();
GEOM::GEOM_Object_ptr anObj = my3DPrimOp->MakeFilling(theShape, theMinDeg, theMaxDeg, theTol2D, theTol3D, theNbIter, theApprox);
GEOM::GEOM_Object_ptr anObj =
my3DPrimOp->MakeFilling(theShape, theMinDeg, theMaxDeg, theTol2D, theTol3D,
theNbIter, theUseOri, theApprox);
endService( " GEOM_Superv_i::MakeFilling" );
return anObj;
}

View File

@ -288,7 +288,8 @@ public:
GEOM::GEOM_Object_ptr MakeFilling (GEOM::GEOM_Object_ptr theShape,
CORBA::Long theMinDeg, CORBA::Long theMaxDeg,
CORBA::Double theTol2D, CORBA::Double theTol3D,
CORBA::Long theNbIter, CORBA::Boolean theApprox);
CORBA::Long theNbIter, CORBA::Boolean theUseOri,
CORBA::Boolean theApprox);
GEOM::GEOM_Object_ptr MakeThruSections(const GEOM::ListOfGO& theSeqSections,
CORBA::Boolean theModeSolid,

View File

@ -1316,6 +1316,7 @@ class geompyDC(GEOM._objref_GEOM_Gen):
# @param theTol2D a 2d tolerance to be reached
# @param theTol3D a 3d tolerance to be reached
# @param theNbIter a number of iteration of approximation algorithm
# @param isUseOri flag for take into account orientation of edges
# @param isApprox if True, BSpline curves are generated in the process
# of surface construction. By default it is False, that means
# the surface is created using Besier curves. The usage of
@ -1324,12 +1325,14 @@ class geompyDC(GEOM._objref_GEOM_Gen):
# @return New GEOM_Object, containing the created filling surface.
#
# @ref tui_creation_filling "Example"
def MakeFilling(self, theShape, theMinDeg, theMaxDeg, theTol2D, theTol3D, theNbIter, isApprox=0):
def MakeFilling(self, theShape, theMinDeg, theMaxDeg, theTol2D,
theTol3D, theNbIter, isUseOri=0, isApprox=0):
# Example: see GEOM_TestAll.py
theMinDeg,theMaxDeg,theTol2D,theTol3D,theNbIter,Parameters = ParseParameters(theMinDeg, theMaxDeg,
theTol2D, theTol3D, theNbIter)
anObj = self.PrimOp.MakeFilling(theShape, theMinDeg, theMaxDeg,
theTol2D, theTol3D, theNbIter, isApprox)
theTol2D, theTol3D, theNbIter,
isUseOri, isApprox)
RaiseIfFailed("MakeFilling", self.PrimOp)
anObj.SetParameters(Parameters)
return anObj

View File

@ -70,6 +70,7 @@ GenerationGUI_FillingDlg::GenerationGUI_FillingDlg( GeometryGUI* theGeometryGUI,
GroupPoints->TextLabel5->setText( tr( "GEOM_FILLING_MAX_DEG" ) );
GroupPoints->TextLabel6->setText( tr( "GEOM_FILLING_TOL_3D" ) );
GroupPoints->CheckBox1->setText( tr( "GEOM_FILLING_APPROX" ) );
GroupPoints->CheckBox2->setText( tr( "GEOM_FILLING_USEORI" ) );
GroupPoints->PushButton1->setIcon( image1 );
GroupPoints->LineEdit1->setReadOnly( true );
@ -108,6 +109,7 @@ void GenerationGUI_FillingDlg::Init()
myTol3D = 0.0001;
myTol2D = 0.0001;
myNbIter = 0;
myIsUseOri = false;
myIsApprox = false;
myOkCompound = false;
@ -141,7 +143,11 @@ void GenerationGUI_FillingDlg::Init()
connect( GroupPoints->SpinBox4, SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox( double ) ) );
connect( GroupPoints->SpinBox5, SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox( double ) ) );
connect( GroupPoints->CheckBox1, SIGNAL( stateChanged( int ) ), this, SLOT( ApproxChanged() ) );
connect( GroupPoints->CheckBox1, SIGNAL( stateChanged( int ) ),
this, SLOT( ApproxChanged() ) );
connect( GroupPoints->CheckBox2, SIGNAL( stateChanged( int ) ),
this, SLOT( UseOriChanged() ) );
connect( myGeomGUI, SIGNAL( SignalDefaultStepValueChanged( double ) ), this, SLOT( SetDoubleSpinBoxStep( double ) ) );
@ -224,7 +230,8 @@ void GenerationGUI_FillingDlg::SelectionIntoArgument()
if (GEOMBase::GetShape(aSelectedObject, S) && S.ShapeType() == TopAbs_COMPOUND) {
// myCompound should be a compound of edges
for (TopoDS_Iterator it (S); it.More(); it.Next())
if (it.Value().ShapeType() != TopAbs_EDGE)
if ( it.Value().ShapeType() != TopAbs_EDGE &&
it.Value().ShapeType() != TopAbs_WIRE )
return;
myCompound = aSelectedObject;
myOkCompound = true;
@ -314,6 +321,16 @@ void GenerationGUI_FillingDlg::ValueChangedInSpinBox( double newValue )
displayPreview();
}
//=================================================================================
// function : UseOriChanged()
// purpose :
//=================================================================================
void GenerationGUI_FillingDlg::UseOriChanged()
{
myIsUseOri = GroupPoints->CheckBox2->isChecked();
displayPreview();
}
//=================================================================================
// function : ApproxChanged()
// purpose :
@ -324,6 +341,7 @@ void GenerationGUI_FillingDlg::ApproxChanged()
displayPreview();
}
//=================================================================================
// function : createOperation
// purpose :
@ -355,9 +373,11 @@ bool GenerationGUI_FillingDlg::isValid( QString& msg )
//=================================================================================
bool GenerationGUI_FillingDlg::execute( ObjectList& objects )
{
GEOM::GEOM_I3DPrimOperations_var anOper = GEOM::GEOM_I3DPrimOperations::_narrow(getOperation());
GEOM::GEOM_Object_var anObj = anOper->MakeFilling( myCompound, myMinDeg, myMaxDeg,
myTol2D, myTol3D, myNbIter, myIsApprox );
GEOM::GEOM_I3DPrimOperations_var anOper =
GEOM::GEOM_I3DPrimOperations::_narrow(getOperation());
GEOM::GEOM_Object_var anObj =
anOper->MakeFilling( myCompound, myMinDeg, myMaxDeg, myTol2D, myTol3D,
myNbIter, myIsUseOri, myIsApprox );
if ( !anObj->_is_nil() )
{
if ( !IsPreview() )

View File

@ -60,6 +60,7 @@ private:
Standard_Real myTol2D;
Standard_Integer myNbIter;
bool myIsApprox;
bool myIsUseOri;
bool myOkCompound; /* to check when curv. compound is defined */
DlgRef_1Sel5Spin1Check* GroupPoints;
@ -72,6 +73,7 @@ private slots:
void SelectionIntoArgument();
void SetEditCurrentArgument();
void ValueChangedInSpinBox( double );
void UseOriChanged();
void ApproxChanged();
void SetDoubleSpinBoxStep( double );
};