0022759: [EDF] Creation of a surface from several edges

This commit is contained in:
mpa 2014-12-08 18:14:18 +03:00
parent 212a371517
commit 34cab1d897
20 changed files with 899 additions and 225 deletions

View File

@ -5,7 +5,7 @@
To create a \b Face in the <b>Main Menu</b> select <b>New Entity - >
Build - > Face</b>
There are two algorithms to create a \b Face. In both cases the \b Result
There are three algorithms to create a \b Face. In all cases the \b Result
of the operation will be a GEOM_Object (FACE).
\n Firstly, to create a \b Face you need to select input shape(s). The list of
@ -20,14 +20,18 @@ that can be interpreted as an outer one; other wires can be considered as
inner ones.
\n Check <b>Try to create a planar face</b> to create a planar
face or nothing if it is impossible.
\note Please note, that the resulting face can have a huge tolerance, if the initial wire has a big deviation from the plane. If the final tolerance exceeds 1e-06, a warning will be shown, but the face will be created and published in the study in a normal way. Using such faces can lead to failures or unpredictable results in most operations.
\note Please note, that the resulting face can have a huge tolerance, if
the initial wire has a big deviation from the plane. If the final tolerance
exceeds 1e-06, a warning will be shown, but the face will be created
and published in the study in a normal way. Using such faces can lead to failures
or unpredictable results in most operations.
\n The \b Result will be a \b GEOM_Object (FACE).
\n <b>TUI Command:</b> <em>geompy.MakeFaceWires([list of Shapes], isPlanarWanted)</em>
\n <b>Arguments:</b> Name + 1 wire.
\image html neo-obj4.png
\image html neo-obj4.png "Create face by input shape(s)"
\n Secondly, it is possible to create a face based on another face's surface and bounded by a wire.
@ -36,7 +40,22 @@ face or nothing if it is impossible.
\n <b>TUI Command:</b> <em>geompy.MakeFaceFromSurface(theFace, theWire)</em>
\n <b>Arguments:</b> Name + 1 face + 1 wire.
\image html neo-obj4_2.png
\image html neo-obj4_2.png "Create face by another face's surface"
Thirdly, user can create a \b Face by specifying a wire and its constraints.
It is necessary to define an input wire by selecting it in the object browser
or in the viewer. The input wire will be exploded on edges which will be shown
in the \b Constraints tree widget.
User must define the constraint face for each edge to get a good result.
\note Please note, that the constraint face must be connected to the edge.
\n The \b Result will be a \b GEOM_Object (FACE).
\n <b>TUI Command:</b> <em>geompy.MakeFaceWithConstraints([List of constraints])</em>
\n <b>Arguments:</b> Name + List of constraints, each constraint is a couple (Edge, Face),
where Edge is an Edge within the source Wire and Face is a Face connected to this Edge.
\image html neo-obj4_3.png "Create face by a wire and its constraints"
\n <b>Example:</b>

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -1938,6 +1938,15 @@ module GEOM
GEOM_Object MakeFaceFromSurface(in GEOM_Object theFace,
in GEOM_Object theWire);
/*!
* \brief Create a face on the given constraints.
* \param theConstraints List of constraints. Each constraint is a couple (Edge, Face),
* where Edge is an Edge of closed Wire
* and Face is a Face connected to this Edge.
* \return New GEOM_Object, containing the created face.
*/
GEOM_Object MakeFaceWithConstraints(in ListOfGO theConstraints);
/*!
* \brief Create a shell from the set of faces and shells.
* \param theFacesAndShells List of faces and/or shells.
@ -2165,6 +2174,21 @@ module GEOM
*/
string GetShapeTypeString (in GEOM_Object theShape);
/*!
* \brief Check, if the object is sub-object of other GEOM object.
*
* \param theSubObject The checked sub-object or its parent object.
* \param theSubObjectIndex If theSubObjectIndex is defined
* this parameter is the index of checked sub-object within the source theSubObject,
* If theSubObjectIndex is not defined the checked sub-object is theSubObject.
* \param theObject The object or its parent.
* \param theObjectIndex The object index within the source theObject.
* \return TRUE, if the given object contains the checked sub-object.
*/
boolean IsSubShapeBelongsTo( in GEOM_Object theSubObject,
in long theSubObjectIndex,
in GEOM_Object theObject,
in long theObjectIndex);
/*!
* \brief Count number of faces in the given shape.
* \param theShape Shape to count faces in.

View File

@ -391,6 +391,7 @@ module GEOM
in boolean isPlanarWanted) ;
GEOM_Object MakeFaceWires (in GEOM_List theWires,
in boolean isPlanarWanted) ;
GEOM_Object MakeFaceWithConstraints(in GEOM_List theConstraints);
GEOM_Object MakeShell (in GEOM_List theFacesAndShells) ;
GEOM_Object MakeSolidShell (in GEOM_Object theShell) ;
GEOM_Object MakeSolidShells (in GEOM_List theShells) ;

View File

@ -4283,6 +4283,28 @@
</outParameter-list>
<DataStream-list></DataStream-list>
</component-service>
<component-service>
<service-name>MakeFaceWithConstraints</service-name>
<service-author>SALOME team</service-author>
<service-version>@SALOMEGEOM_VERSION@</service-version>
<service-comment>unknown</service-comment>
<service-by-default>0</service-by-default>
<inParameter-list>
<inParameter>
<inParameter-name>theConstraints</inParameter-name>
<inParameter-type>GEOM/GEOM_List</inParameter-type>
<inParameter-comment>unknown</inParameter-comment>
</inParameter>
</inParameter-list>
<outParameter-list>
<outParameter>
<outParameter-name>return</outParameter-name>
<outParameter-type>GEOM/GEOM_Object</outParameter-type>
<outParameter-comment>unknown</outParameter-comment>
</outParameter>
</outParameter-list>
<DataStream-list></DataStream-list>
</component-service>
<component-service>
<service-name>MakeSolidShell</service-name>
<service-author>SALOME team</service-author>

View File

@ -50,12 +50,14 @@
//=================================================================================
BuildGUI_FaceDlg::BuildGUI_FaceDlg( GeometryGUI* theGeometryGUI, QWidget* parent )
: GEOMBase_Skeleton( theGeometryGUI, parent ),
GroupWire (0),
myGroupSurf (0)
myGroupWire(0),
myGroupSurf(0),
myGroupWireConstraints(0)
{
QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_BUILD_FACE" ) ) );
QPixmap image2( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_BUILD_FACE_SURFACE" ) ) );
QPixmap image3( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_BUILD_FACE_CONSTRAINTS" ) ) );
setWindowTitle( tr( "GEOM_FACE_TITLE" ) );
@ -63,15 +65,18 @@ BuildGUI_FaceDlg::BuildGUI_FaceDlg( GeometryGUI* theGeometryGUI, QWidget* parent
mainFrame()->GroupConstructors->setTitle( tr( "GEOM_FACE" ) );
mainFrame()->RadioButton1->setIcon( image1 );
mainFrame()->RadioButton2->setIcon( image2 );
mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
mainFrame()->RadioButton3->close();
mainFrame()->RadioButton3->setIcon( image3 );
GroupWire = new DlgRef_1Sel1Check( centralWidget() );
// Face creation from wires and/or edges
GroupWire->GroupBox1->setTitle( tr( "GEOM_FACE_FFW" ) );
GroupWire->TextLabel1->setText( tr( "GEOM_OBJECTS" ) );
GroupWire->CheckButton1->setText( tr( "GEOM_FACE_OPT" ) );
GroupWire->PushButton1->setIcon( image0 );
myGroupWire = new DlgRef_1Sel1Check( centralWidget() );
myGroupWire->GroupBox1->setTitle( tr( "GEOM_FACE_FFW" ) );
myGroupWire->TextLabel1->setText( tr( "GEOM_OBJECTS" ) );
myGroupWire->CheckButton1->setText( tr( "GEOM_FACE_OPT" ) );
myGroupWire->PushButton1->setIcon( image0 );
// Face creation from surface
myGroupSurf = new DlgRef_2Sel(centralWidget());
@ -80,11 +85,35 @@ BuildGUI_FaceDlg::BuildGUI_FaceDlg( GeometryGUI* theGeometryGUI, QWidget* parent
myGroupSurf->TextLabel2->setText(tr("GEOM_WIRE"));
myGroupSurf->PushButton1->setIcon(image0);
myGroupSurf->PushButton2->setIcon(image0);
// Face creation from wire and constraints
myGroupWireConstraints = new DlgRef_1SelExt( centralWidget() );
myGroupWireConstraints->GroupBox1->setTitle( tr( "GEOM_FACE_FFWC" ) );
myGroupWireConstraints->TextLabel1->setText( tr( "GEOM_WIRE" ) );
myGroupWireConstraints->PushButton1->setIcon( image0 );
QLabel* aLabel = new QLabel( tr( "GEOM_CONSTRAINTS" ) );
myTreeConstraints = new QTreeWidget( myGroupWireConstraints->Box );
myTreeConstraints->setColumnCount(2);
QStringList columnNames;
columnNames.append( tr( "GEOM_EDGE" ));
columnNames.append( tr( "GEOM_FACE_CONSTRAINT" ) );
myTreeConstraints->setHeaderLabels( columnNames );
myTreeConstraints->header()->setMovable( false );
myTreeConstraints->header()->setResizeMode( QHeaderView::ResizeToContents );
myTreeConstraints->setFixedHeight( 140 );
QHBoxLayout* l = new QHBoxLayout( myGroupWireConstraints->Box );
l->setMargin( 0 ); l->setSpacing( 6 );
l->addWidget( aLabel);
l->addWidget( myTreeConstraints );
QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
layout->setMargin( 0 ); layout->setSpacing( 6 );
layout->addWidget( GroupWire );
layout->addWidget( myGroupWire );
layout->addWidget(myGroupSurf);
layout->addWidget( myGroupWireConstraints );
/***************************************************************/
setHelpFileName("create_face_page.html");
@ -111,33 +140,39 @@ BuildGUI_FaceDlg::~BuildGUI_FaceDlg()
void BuildGUI_FaceDlg::Init()
{
/* init variables */
myEditCurrentArgument = GroupWire->LineEdit1;
GroupWire->LineEdit1->setReadOnly( true );
myEditCurrentArgument = myGroupWire->LineEdit1;
myGroupWire->LineEdit1->setReadOnly( true );
myGroupSurf->LineEdit1->setReadOnly( true );
myGroupSurf->LineEdit2->setReadOnly( true );
myGroupWireConstraints->LineEdit1->setReadOnly( true );
GroupWire->CheckButton1->setChecked( true );
myGroupWire->CheckButton1->setChecked( true );
myWires.clear();
myFace.nullify();
myWire.nullify();
myCurrentItem = NULL;
/* signals and slots connections */
connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
connect(this, SIGNAL( constructorsClicked( int ) ), this, SLOT( ConstructorsClicked( int ) ) );
connect( buttonOk(), SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
connect( GroupWire->LineEdit1, SIGNAL( returnPressed()), this, SLOT( LineEditReturnPressed() ) );
connect( GroupWire->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
connect( myGroupWire->LineEdit1, SIGNAL( returnPressed()), this, SLOT( LineEditReturnPressed() ) );
connect( myGroupWire->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
connect( myGroupSurf->LineEdit1, SIGNAL( returnPressed()), this, SLOT( LineEditReturnPressed() ) );
connect( myGroupSurf->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
connect( myGroupSurf->LineEdit2, SIGNAL( returnPressed()), this, SLOT( LineEditReturnPressed() ) );
connect( myGroupSurf->PushButton2, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
connect( myGroupWireConstraints->LineEdit1, SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
connect( myGroupWireConstraints->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
connect( ( (SalomeApp_Application*)( SUIT_Session::session()->activeApplication() ) )->selectionMgr(),
SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
connect( myTreeConstraints, SIGNAL( itemClicked( QTreeWidgetItem*, int) ), this, SLOT( onItemClicked( QTreeWidgetItem*, int ) ) );
initName( tr( "GEOM_FACE" ) );
ConstructorsClicked(0);
@ -162,22 +197,40 @@ void BuildGUI_FaceDlg::ConstructorsClicked(int constructorId)
aMap.Add(GEOM_COMPOUND);
globalSelection(aMap);
myEditCurrentArgument = GroupWire->LineEdit1;
GroupWire->LineEdit1->setText("");
GroupWire->show();
myEditCurrentArgument = myGroupWire->LineEdit1;
myGroupWire->LineEdit1->setText("");
myGroupWire->show();
myGroupSurf->hide();
myGroupWireConstraints->hide();
break;
}
case 1:
{
globalSelection(GEOM_FACE); // For the first element.
localSelection( GEOM::GEOM_Object::_nil(), TopAbs_FACE );
myEditCurrentArgument = myGroupSurf->LineEdit1;
myGroupSurf->LineEdit1->setText("");
myGroupSurf->PushButton1->setDown(true);
myGroupSurf->PushButton2->setDown(false);
GroupWire->hide();
myGroupWire->hide();
myGroupSurf->show();
myGroupWireConstraints->hide();
break;
}
case 2:
{
globalSelection();
localSelection( GEOM::GEOM_Object::_nil(), TopAbs_WIRE );
myTreeConstraints->clear();
myCurrentItem = NULL;
myEditCurrentArgument = myGroupWireConstraints->LineEdit1;
myGroupWireConstraints->LineEdit1->setText("");
myGroupWireConstraints->LineEdit1->setEnabled(true);
myGroupWire->hide();
myGroupSurf->hide();
myGroupWireConstraints->show();
break;
}
}
@ -191,6 +244,73 @@ void BuildGUI_FaceDlg::ConstructorsClicked(int constructorId)
SelectionIntoArgument();
}
//=================================================================================
// function : updateContraintsTree
// purpose :
//=================================================================================
void BuildGUI_FaceDlg::updateContraintsTree()
{
if( myEditCurrentArgument != myGroupWireConstraints->LineEdit1 || myWire.isNull() )
return;
myTreeConstraints->clear();
GEOM::GEOM_IShapesOperations_ptr anOper = GEOM::GEOM_IShapesOperations::_narrow(getOperation());
GEOM::ListOfGO_var aList = anOper->ExtractSubShapes( myWire.get(), TopAbs_EDGE, false );
if( !aList->length() )
return;
for( int i = 0, n = aList->length(); i < n; i++ ) {
BuildGUI_TreeWidgetItem* item = new BuildGUI_TreeWidgetItem( myTreeConstraints,
GEOM::GeomObjPtr( aList[i] ) );
}
myEditCurrentArgument->setEnabled(false);
globalSelection();
localSelection( GEOM::GEOM_Object::_nil(), TopAbs_FACE );
myTreeConstraints->resizeColumnToContents(0);
QTreeWidgetItem* firstItem = myTreeConstraints->topLevelItem(0);
firstItem->setSelected( true );
onItemClicked( firstItem ,0 );
}
//=================================================================================
// function : findEmptyTreeItem()
// purpose :
//=================================================================================
void BuildGUI_FaceDlg::findEmptyTreeItem()
{
if( isTreeFull() )
return;
myCurrentItem->setSelected( false );
BuildGUI_TreeWidgetItem* itemBelow = dynamic_cast<BuildGUI_TreeWidgetItem*>( myTreeConstraints->itemBelow( myCurrentItem ) );
if( !itemBelow )
itemBelow = dynamic_cast<BuildGUI_TreeWidgetItem*>( myTreeConstraints->topLevelItem(0) );
myCurrentItem = itemBelow;
if( itemBelow->getFace().isNull() ) {
itemBelow->setSelected( true );
onItemClicked( itemBelow, 0 );
}
else
findEmptyTreeItem();
}
//=================================================================================
// function : isTreeFull()
// purpose :
//=================================================================================
bool BuildGUI_FaceDlg::isTreeFull()
{
QTreeWidgetItem* item = myTreeConstraints->topLevelItem(0);
while( !(dynamic_cast<BuildGUI_TreeWidgetItem*>(item))->getFace().isNull() ) {
item = myTreeConstraints->itemBelow( item );
if( !item )
return true;
}
return false;
}
//=================================================================================
// function : ClickOnOk()
// purpose :
@ -213,6 +333,9 @@ bool BuildGUI_FaceDlg::ClickOnApply()
return false;
initName();
myEditCurrentArgument->setText("");
ConstructorsClicked( getConstructorId() );
return true;
}
@ -223,8 +346,8 @@ bool BuildGUI_FaceDlg::ClickOnApply()
//=================================================================================
void BuildGUI_FaceDlg::SelectionIntoArgument()
{
if (myEditCurrentArgument == GroupWire->LineEdit1) {
myEditCurrentArgument->setText( "" );
if( myEditCurrentArgument == myGroupWire->LineEdit1 ) {
myEditCurrentArgument->setText("");
QList<TopAbs_ShapeEnum> types;
types << TopAbs_EDGE << TopAbs_WIRE << TopAbs_FACE
@ -235,7 +358,8 @@ void BuildGUI_FaceDlg::SelectionIntoArgument()
QString aName = myWires.count() > 1 ? QString( "%1_objects").arg( myWires.count() ) : GEOMBase::GetName( myWires[0].get() );
myEditCurrentArgument->setText( aName );
}
} else if (myEditCurrentArgument == myGroupSurf->LineEdit1 ||
}
else if (myEditCurrentArgument == myGroupSurf->LineEdit1 ||
myEditCurrentArgument == myGroupSurf->LineEdit2) {
const bool isEditFace = myEditCurrentArgument == myGroupSurf->LineEdit1;
const TopAbs_ShapeEnum aType = isEditFace ? TopAbs_FACE : TopAbs_WIRE;
@ -260,8 +384,37 @@ void BuildGUI_FaceDlg::SelectionIntoArgument()
}
}
}
displayPreview(true);
else if( myEditCurrentArgument == myGroupWireConstraints->LineEdit1 ) {
if( myCurrentItem != NULL ) {
GEOM::GeomObjPtr aSelectedObject = getSelected( TopAbs_FACE );
TopoDS_Shape aFaceShape;
GEOM::GEOM_IShapesOperations_ptr anOper = GEOM::GEOM_IShapesOperations::_narrow(getOperation());
if( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aFaceShape ) && !aFaceShape.IsNull()
&& anOper->IsSubShapeBelongsTo( myCurrentItem->getEdge().get(), 0, aSelectedObject.get(), 0 ) ) {
myCurrentItem->setFace( aSelectedObject );
findEmptyTreeItem();
}
else
myCurrentItem->setFace(NULL);
}
else {
myWire.nullify();
myEditCurrentArgument->setText( "" );
GEOM::GeomObjPtr aSelectedObject = getSelected( TopAbs_WIRE );
TopoDS_Shape aWireShape;
if( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aWireShape ) && !aWireShape.IsNull() ) {
QString aName = GEOMBase::GetName( aSelectedObject.get() );
myEditCurrentArgument->setText(aName);
myWire = aSelectedObject;
updateContraintsTree();
}
else {
myTreeConstraints->clear();
erasePreview(true);
}
}
}
//displayPreview(true);
}
@ -272,7 +425,7 @@ void BuildGUI_FaceDlg::SelectionIntoArgument()
void BuildGUI_FaceDlg::SetEditCurrentArgument()
{
QPushButton* send = (QPushButton*)sender();
if (send == GroupWire->PushButton1) {
if( send == myGroupWire->PushButton1 ) {
TColStd_MapOfInteger aMap;
aMap.Add(GEOM_EDGE);
@ -282,26 +435,33 @@ void BuildGUI_FaceDlg::SetEditCurrentArgument()
aMap.Add(GEOM_SOLID);
aMap.Add(GEOM_COMPOUND);
globalSelection(aMap);
myEditCurrentArgument = GroupWire->LineEdit1;
myEditCurrentArgument = myGroupWire->LineEdit1;
}
else if (send == myGroupSurf->PushButton1) {
globalSelection(GEOM_FACE);
localSelection( GEOM::GEOM_Object::_nil(), TopAbs_FACE );
myEditCurrentArgument = myGroupSurf->LineEdit1;
myGroupSurf->PushButton2->setDown(false);
myGroupSurf->LineEdit2->setEnabled(false);
}
else if (send == myGroupSurf->PushButton2) {
globalSelection(GEOM_WIRE);
localSelection( GEOM::GEOM_Object::_nil(), TopAbs_WIRE );
myEditCurrentArgument = myGroupSurf->LineEdit2;
myGroupSurf->PushButton1->setDown(false);
myGroupSurf->LineEdit1->setEnabled(false);
}
else if(send == myGroupWireConstraints->PushButton1) {
globalSelection();
localSelection( GEOM::GEOM_Object::_nil(), TopAbs_WIRE );
myEditCurrentArgument = myGroupWireConstraints->LineEdit1;
myCurrentItem = NULL;
}
// enable line edit
myEditCurrentArgument->setEnabled(true);
myEditCurrentArgument->setFocus();
send->setDown(true);
displayPreview(true);
SelectionIntoArgument();
}
@ -320,6 +480,19 @@ void BuildGUI_FaceDlg::ActivateThisDialog()
ConstructorsClicked(getConstructorId());
}
//=================================================================================
// function : onItemClicked()
// purpose : called when tree item was clicked
//=================================================================================
void BuildGUI_FaceDlg::onItemClicked( QTreeWidgetItem* theItem, int theColumn )
{
if(!( theItem->flags() & Qt::ItemIsSelectable ) )
return;
myCurrentItem = dynamic_cast<BuildGUI_TreeWidgetItem*>( theItem );
erasePreview();
displayPreview( myCurrentItem->getEdge().get(), true, false, true, 5, -1, Quantity_NOC_RED);
}
//=================================================================================
// function : enterEvent()
@ -355,6 +528,9 @@ bool BuildGUI_FaceDlg::isValid( QString& )
case 1:
ok = myFace && myWire;
break;
case 2:
ok = myWire;
break;
default:
break;
}
@ -383,13 +559,30 @@ bool BuildGUI_FaceDlg::execute( ObjectList& objects )
objlist[i] = myWires[i].copy();
}
anObj = anOper->MakeFaceWires( objlist.in(), GroupWire->CheckButton1->isChecked() );
res = true;
anObj = anOper->MakeFaceWires( objlist.in(), myGroupWire->CheckButton1->isChecked() );
res = true;
}
break;
case 1:
anObj = anOper->MakeFaceFromSurface(myFace.get(), myWire.get());
res = true;
res = true;
break;
case 2:
{
int numberOfItems = myTreeConstraints->topLevelItemCount();
GEOM::ListOfGO_var constraints = new GEOM::ListOfGO();
constraints->length( 2 * numberOfItems );
int j = 0;
for( int i = 0; i < numberOfItems; i++ ) {
BuildGUI_TreeWidgetItem* item = dynamic_cast<BuildGUI_TreeWidgetItem*>( myTreeConstraints->topLevelItem(i) );
constraints[j++] = item->getEdge().get();
if ( item->getFace() )
constraints[j++] = item->getFace().get();
}
constraints->length(j);
anObj = anOper->MakeFaceWithConstraints( constraints.in() );
res = true;
}
break;
default:
break;
@ -409,3 +602,62 @@ bool BuildGUI_FaceDlg::execute( ObjectList& objects )
return res;
}
//=================================================================================
// function : addSubshapeToStudy
// purpose : virtual method to add new SubObjects if local selection
//=================================================================================
void BuildGUI_FaceDlg::addSubshapesToStudy()
{
switch (getConstructorId()) {
case 0:
break;
case 1:
break;
case 2:
for( int i = 0; i < myTreeConstraints->topLevelItemCount(); i++ ) {
BuildGUI_TreeWidgetItem* item = dynamic_cast<BuildGUI_TreeWidgetItem*>( myTreeConstraints->topLevelItem(i) );
if( item->getFace().get() )
GEOMBase::PublishSubObject( item->getFace().get() );
GEOMBase::PublishSubObject( myWire.get() );
}
break;
default:
break;
}
}
BuildGUI_TreeWidgetItem::BuildGUI_TreeWidgetItem( QTreeWidget* view, const GEOM::GeomObjPtr edge, int type )
:QTreeWidgetItem( view, QStringList()<<GEOMBase::GetName( edge.get() ), type ),
myEdge( edge ),
myFace( NULL )
{
}
BuildGUI_TreeWidgetItem::BuildGUI_TreeWidgetItem( QTreeWidgetItem* parent, const GEOM::GeomObjPtr edge, int type )
:QTreeWidgetItem( parent, QStringList()<<GEOMBase::GetName( edge.get() ), type ),
myEdge( edge ),
myFace( NULL )
{
}
BuildGUI_TreeWidgetItem::~BuildGUI_TreeWidgetItem()
{
}
void BuildGUI_TreeWidgetItem::setFace( const GEOM::GeomObjPtr face)
{
QString aName = GEOMBase::GetName( face.get() );
setText( 1, aName );
treeWidget()->resizeColumnToContents(1);
myFace = face;
}
GEOM::GeomObjPtr BuildGUI_TreeWidgetItem::getFace() const
{
return myFace;
}
GEOM::GeomObjPtr BuildGUI_TreeWidgetItem::getEdge() const
{
return myEdge;
}

View File

@ -30,8 +30,29 @@
#include "GEOMBase_Skeleton.h"
#include "GEOM_GenericObjPtr.h"
#include <QTreeWidget>
class DlgRef_1Sel1Check;
class DlgRef_2Sel;
class DlgRef_1SelExt;
//=================================================================================
// class : BuildGUI_TreeWidgetItem
// purpose : class for constraint(Edge-Face) creation
//=================================================================================
class BuildGUI_TreeWidgetItem : public QTreeWidgetItem
{
public:
BuildGUI_TreeWidgetItem( QTreeWidget*, const GEOM::GeomObjPtr, int = Type );
BuildGUI_TreeWidgetItem( QTreeWidgetItem*, const GEOM::GeomObjPtr, int = Type );
~BuildGUI_TreeWidgetItem();
void setFace( const GEOM::GeomObjPtr );
GEOM::GeomObjPtr getFace() const;
GEOM::GeomObjPtr getEdge() const;
private:
GEOM::GeomObjPtr myEdge;
GEOM::GeomObjPtr myFace;
};
//=================================================================================
// class : BuildGUI_FaceDlg
@ -50,26 +71,35 @@ protected:
virtual GEOM::GEOM_IOperations_ptr createOperation();
virtual bool isValid( QString& );
virtual bool execute( ObjectList& );
virtual void addSubshapesToStudy();
private:
void Init();
void enterEvent( QEvent* );
void updateContraintsTree();
void findEmptyTreeItem();
bool isTreeFull();
private:
QList<GEOM::GeomObjPtr> myWires;
GEOM::GeomObjPtr myFace;
GEOM::GeomObjPtr myWire;
DlgRef_1Sel1Check* GroupWire;
DlgRef_1Sel1Check* myGroupWire;
DlgRef_2Sel* myGroupSurf;
DlgRef_1SelExt* myGroupWireConstraints;
QTreeWidget* myTreeConstraints;
BuildGUI_TreeWidgetItem* myCurrentItem;
private slots:
void ConstructorsClicked (int);
void ConstructorsClicked( int );
void ClickOnOk();
bool ClickOnApply();
void ActivateThisDialog();
void SelectionIntoArgument();
void SetEditCurrentArgument();
void onItemClicked( QTreeWidgetItem*, int );
};
#endif // BUILDGUI_FACEDLG_H

View File

@ -163,6 +163,10 @@
<source>ICON_DLG_BUILD_FACE_SURFACE</source>
<translation>build_face_surface.png</translation>
</message>
<message>
<source>ICON_DLG_BUILD_FACE_CONSTRAINTS</source>
<translation>build_face_constraints.png</translation>
</message>
<message>
<source>ICON_DLG_FACE_HW</source>
<translation>face_hw.png</translation>

View File

@ -707,6 +707,18 @@ Please, select face, shell or solid and try again</translation>
<source>GEOM_FACE_OPT</source>
<translation>Try to create a planar face</translation>
</message>
<message>
<source>GEOM_FACE_FFWC</source>
<translation>Face creation from wire and constraints</translation>
</message>
<message>
<source>GEOM_CONSTRAINTS</source>
<translation>Constraints</translation>
</message>
<message>
<source>GEOM_FACE_CONSTRAINT</source>
<translation>Constraint Face</translation>
</message>
<message>
<source>GEOM_SOLID_FROM_FACE_OPT</source>
<translation>Intersect shapes</translation>

View File

@ -723,6 +723,18 @@ Choisissez une face, une coque ou un solide et essayez de nouveau</translation>
<source>GEOM_FACE_OPT</source>
<translation>Privilégier la création d&apos;une face plane</translation>
</message>
<message>
<source>GEOM_FACE_FFWC</source>
<translation type="unfinished">Face creation from wire and constraints</translation>
</message>
<message>
<source>GEOM_CONSTRAINTS</source>
<translation type="unfinished">Constraints</translation>
</message>
<message>
<source>GEOM_FACE_CONSTRAINT</source>
<translation type="unfinished">Constraint Face</translation>
</message>
<message>
<source>GEOM_SOLID_FROM_FACE_OPT</source>
<translation type="unfinished">Intersect shapes</translation>

View File

@ -703,6 +703,18 @@
<source>GEOM_FACE_OPT</source>
<translation></translation>
</message>
<message>
<source>GEOM_FACE_FFWC</source>
<translation type="unfinished">Face creation from wire and constraints</translation>
</message>
<message>
<source>GEOM_CONSTRAINTS</source>
<translation type="unfinished">Constraints</translation>
</message>
<message>
<source>GEOM_FACE_CONSTRAINT</source>
<translation type="unfinished">Constraint Face</translation>
</message>
<message>
<source>GEOM_SOLID_FROM_FACE_OPT</source>
<translation type="unfinished">Intersect shapes</translation>

View File

@ -35,6 +35,7 @@
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepOffsetAPI_MakeFilling.hxx>
#include <GeomAPI_PointsToBSpline.hxx>
#include <GeomAPI_PointsToBSplineSurface.hxx>
@ -64,6 +65,7 @@
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Vertex.hxx>
@ -97,211 +99,249 @@ Standard_Integer GEOMImpl_FillingDriver::Execute(TFunction_Logbook& log) const
if (Label().IsNull()) return 0;
Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
if (aFunction.IsNull()) return 0;
if (aFunction->GetType() != BASIC_FILLING) return 0;
TopoDS_Shape aShape;
GEOMImpl_IFilling IF (aFunction);
Standard_Integer mindeg = IF.GetMinDeg();
Standard_Integer maxdeg = IF.GetMaxDeg();
Standard_Real tol3d = IF.GetTol3D();
Standard_Boolean isApprox = IF.GetApprox();
if (mindeg > maxdeg) {
Standard_RangeError::Raise("Minimal degree can not be more than maximal degree");
}
/* we verify the contents of the shape */
TopExp_Explorer Ex;
TopoDS_Shape Scurrent;
Standard_Real First, Last;
Handle(Geom_Curve) C;
TopoDS_Compound aComp;
BRep_Builder B;
B.MakeCompound(aComp);
// input is either a list or compound of contours
TopTools_SequenceOfShape contours;
Handle(TColStd_HSequenceOfTransient) aShapeFunctions = IF.GetShapes();
if ( aShapeFunctions.IsNull() || aShapeFunctions->IsEmpty() ) return 0;
for ( int i = 1; i <= aShapeFunctions->Length(); ++i )
if( aFunction->GetType() == BASIC_FILLING )
{
Handle(GEOM_Function) fun = Handle(GEOM_Function)::DownCast( aShapeFunctions->Value( i ));
if ( fun.IsNull() ) return 0;
TopoDS_Shape s = fun->GetValue();
if ( s.IsNull() ) return 0;
BRepBuilderAPI_Copy Copy (s);
if ( Copy.IsDone() )
contours.Append( Copy.Shape() );
}
GEOMImpl_IFilling IF (aFunction);
Standard_Integer mindeg = IF.GetMinDeg();
Standard_Integer maxdeg = IF.GetMaxDeg();
Standard_Real tol3d = IF.GetTol3D();
Standard_Boolean isApprox = IF.GetApprox();
// 1. Convert argument wires, if any, into BSpline edges
for ( int i = 1; i <= contours.Length(); ++i )
{
Scurrent = contours.Value( i );
if (Scurrent.ShapeType() != TopAbs_EDGE) {
if (Scurrent.ShapeType() == TopAbs_WIRE)
{
const TopoDS_Wire& CurWire = TopoDS::Wire(Scurrent);
TopoDS_Edge NewEdge = BRepAlgo::ConcatenateWireC0(CurWire);
if (NewEdge.IsNull())
Standard_ConstructionError::Raise("Failed to join several edges into one");
Scurrent = NewEdge;
}
else if (Scurrent.ShapeType() == TopAbs_COMPOUND)
{
for ( TopoDS_Iterator It( Scurrent ); It.More(); It.Next() )
contours.Append( It.Value() );
continue;
}
else
{
Standard_ConstructionError::Raise("Input must contain only edges or/and wires");
}
if (mindeg > maxdeg) {
Standard_RangeError::Raise("Minimal degree can not be more than maximal degree");
}
B.Add(aComp,Scurrent);
}
TopoDS_Shape aShape = aComp;
// 2. The surface construction
if (!isApprox) {
// make filling as in old version of SALOME (before 4.1.1)
/* we verify the contents of the shape */
TopExp_Explorer Ex;
TopoDS_Shape Scurrent;
Standard_Real First, Last;
Handle(Geom_Curve) C;
Standard_Real tol2d = IF.GetTol2D();
Standard_Integer nbiter = IF.GetNbIter();
Standard_Integer aMethod = IF.GetMethod();
TopoDS_Compound aComp;
BRep_Builder B;
B.MakeCompound(aComp);
GeomFill_SectionGenerator Section;
Standard_Integer i = 0;
Handle(Geom_Curve) aLastC;
gp_Pnt PL1,PL2;
for (Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next()) {
Scurrent = Ex.Current();
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);
C = new Geom_TrimmedCurve(C, First, Last);
gp_Pnt P1,P2;
C->D0(First,P1);
C->D0(Last,P2);
// input is either a list or compound of contours
TopTools_SequenceOfShape contours;
Handle(TColStd_HSequenceOfTransient) aShapeFunctions = IF.GetShapes();
if ( aShapeFunctions.IsNull() || aShapeFunctions->IsEmpty() ) return 0;
for ( int i = 1; i <= aShapeFunctions->Length(); ++i )
{
Handle(GEOM_Function) fun = Handle(GEOM_Function)::DownCast( aShapeFunctions->Value( i ));
if ( fun.IsNull() ) return 0;
TopoDS_Shape s = fun->GetValue();
if ( s.IsNull() ) return 0;
BRepBuilderAPI_Copy Copy (s);
if ( Copy.IsDone() )
contours.Append( Copy.Shape() );
}
if (aMethod == 1 && Scurrent.Orientation() == TopAbs_REVERSED) {
C->Reverse();
}
else if (aMethod == 2) {
if (i == 0) {
PL1 = P1;
PL2 = P2;
// 1. Convert argument wires, if any, into BSpline edges
for ( int i = 1; i <= contours.Length(); ++i )
{
Scurrent = contours.Value( i );
if (Scurrent.ShapeType() != TopAbs_EDGE) {
if (Scurrent.ShapeType() == TopAbs_WIRE)
{
const TopoDS_Wire& CurWire = TopoDS::Wire(Scurrent);
TopoDS_Edge NewEdge = BRepAlgo::ConcatenateWireC0(CurWire);
if (NewEdge.IsNull())
Standard_ConstructionError::Raise("Failed to join several edges into one");
Scurrent = NewEdge;
}
else {
double d1 = PL1.Distance(P1) + PL2.Distance(P2);
double d2 = PL1.Distance(P2) + PL2.Distance(P1);
if (d2 < d1) {
C->Reverse();
PL1 = P2;
PL2 = P1;
}
else {
else if (Scurrent.ShapeType() == TopAbs_COMPOUND)
{
for ( TopoDS_Iterator It( Scurrent ); It.More(); It.Next() )
contours.Append( It.Value() );
continue;
}
else
{
Standard_ConstructionError::Raise("Input must contain only edges or/and wires");
}
}
B.Add(aComp,Scurrent);
}
aShape = aComp;
// 2. The surface construction
if (!isApprox) {
// make filling as in old version of SALOME (before 4.1.1)
Standard_Real tol2d = IF.GetTol2D();
Standard_Integer nbiter = IF.GetNbIter();
Standard_Integer aMethod = IF.GetMethod();
GeomFill_SectionGenerator Section;
Standard_Integer i = 0;
Handle(Geom_Curve) aLastC;
gp_Pnt PL1,PL2;
for (Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next()) {
Scurrent = Ex.Current();
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);
C = new Geom_TrimmedCurve(C, First, Last);
gp_Pnt P1,P2;
C->D0(First,P1);
C->D0(Last,P2);
if (aMethod == 1 && Scurrent.Orientation() == TopAbs_REVERSED) {
C->Reverse();
}
else if (aMethod == 2) {
if (i == 0) {
PL1 = P1;
PL2 = P2;
}
}
}
Section.AddCurve(C);
i++;
}
/* a 'tolerance' is used to compare 2 knots : see GeomFill_Generator.cdl */
Section.Perform(Precision::PConfusion());
Handle(GeomFill_Line) Line = new GeomFill_Line(i);
GeomFill_AppSurf App (mindeg, maxdeg, tol3d, tol2d, nbiter); /* user parameters */
App.Perform(Line, Section);
if (!App.IsDone()) return 0;
Standard_Integer UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots;
App.SurfShape(UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots);
Handle(Geom_BSplineSurface) GBS = new Geom_BSplineSurface
(App.SurfPoles(), App.SurfWeights(), App.SurfUKnots(), App.SurfVKnots(),
App.SurfUMults(), App.SurfVMults(), App.UDegree(), App.VDegree());
if (GBS.IsNull()) return 0;
aShape = BRepBuilderAPI_MakeFace(GBS, Precision::Confusion());
}
else {
// implemented by skl 20.03.2008 for bug 16568
// make approximation - try to create bspline surface
// using GeomAPI_PointsToBSplineSurface
TColGeom_SequenceOfCurve aSeq;
int MaxNbPoles = 0;
// add curves from edges to sequence and find maximal
// number of poles if some of them are bsplines
for (Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next()) {
Scurrent = Ex.Current();
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);
Handle(Geom_TrimmedCurve) TC = Handle(Geom_TrimmedCurve)::DownCast(C);
if (TC.IsNull()) {
Handle(Geom_BSplineCurve) BC = Handle(Geom_BSplineCurve)::DownCast(C);
if (!BC.IsNull()) {
MaxNbPoles = Max(MaxNbPoles,BC->NbPoles());
}
}
else {
Handle(Geom_BSplineCurve) BC = Handle(Geom_BSplineCurve)::DownCast(TC->BasisCurve());
if (BC.IsNull()) {
Handle(Geom_TrimmedCurve) TC1 = Handle(Geom_TrimmedCurve)::DownCast(TC->BasisCurve());
if (!TC1.IsNull()) {
BC = Handle(Geom_BSplineCurve)::DownCast(TC1->BasisCurve());
else {
double d1 = PL1.Distance(P1) + PL2.Distance(P2);
double d2 = PL1.Distance(P2) + PL2.Distance(P1);
if (d2 < d1) {
C->Reverse();
PL1 = P2;
PL2 = P1;
}
else {
PL1 = P1;
PL2 = P2;
}
}
}
if (!BC.IsNull()) {
MaxNbPoles = Max(MaxNbPoles,BC->NbPoles());
}
Section.AddCurve(C);
i++;
}
aSeq.Append(C);
}
// prepare array of points for creation bspline surface
// size of this array: by U parameter - number of curves,
// by V parameter - determ using MaxNbPoles but it's
// value must be between 21(min) and 101(max)
int nbc = aSeq.Length();
int nbp = Max(21, 2*MaxNbPoles-1);
// commented for Mantis issue 0021541
//if (nbp > 101) nbp = 101;
/* a 'tolerance' is used to compare 2 knots : see GeomFill_Generator.cdl */
Section.Perform(Precision::PConfusion());
Handle(GeomFill_Line) Line = new GeomFill_Line(i);
TColgp_Array2OfPnt Points (1, nbc, 1, nbp);
int ic = 1;
for (; ic <= nbc; ic++) {
Handle(Geom_Curve) C = aSeq.Value(ic);
double fp = C->FirstParameter();
double lp = C->LastParameter();
double dp = (lp-fp)/(nbp-1);
int j = 0;
gp_Pnt P;
for (; j < nbp; j++) {
C->D0(fp+dp*j, P);
Points.SetValue(ic, j+1, P);
}
GeomFill_AppSurf App (mindeg, maxdeg, tol3d, tol2d, nbiter); /* user parameters */
App.Perform(Line, Section);
if (!App.IsDone()) return 0;
Standard_Integer UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots;
App.SurfShape(UDegree, VDegree, NbUPoles, NbVPoles, NbUKnots, NbVKnots);
Handle(Geom_BSplineSurface) GBS = new Geom_BSplineSurface
(App.SurfPoles(), App.SurfWeights(), App.SurfUKnots(), App.SurfVKnots(),
App.SurfUMults(), App.SurfVMults(), App.UDegree(), App.VDegree());
if (GBS.IsNull()) return 0;
aShape = BRepBuilderAPI_MakeFace(GBS, Precision::Confusion());
}
GeomAPI_PointsToBSplineSurface PTB (Points, mindeg, maxdeg, GeomAbs_C2, tol3d);
Handle(Geom_BSplineSurface) BS = PTB.Surface();
BRepBuilderAPI_MakeFace BB (BS, Precision::Confusion());
TopoDS_Face NewF = BB.Face();
Handle(ShapeFix_Face) sff = new ShapeFix_Face (NewF);
sff->Perform();
sff->FixOrientation();
aShape = sff->Face();
else {
// implemented by skl 20.03.2008 for bug 16568
// make approximation - try to create bspline surface
// using GeomAPI_PointsToBSplineSurface
TColGeom_SequenceOfCurve aSeq;
int MaxNbPoles = 0;
// add curves from edges to sequence and find maximal
// number of poles if some of them are bsplines
for (Ex.Init(aShape, TopAbs_EDGE); Ex.More(); Ex.Next()) {
Scurrent = Ex.Current();
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);
Handle(Geom_TrimmedCurve) TC = Handle(Geom_TrimmedCurve)::DownCast(C);
if (TC.IsNull()) {
Handle(Geom_BSplineCurve) BC = Handle(Geom_BSplineCurve)::DownCast(C);
if (!BC.IsNull()) {
MaxNbPoles = Max(MaxNbPoles,BC->NbPoles());
}
}
else {
Handle(Geom_BSplineCurve) BC = Handle(Geom_BSplineCurve)::DownCast(TC->BasisCurve());
if (BC.IsNull()) {
Handle(Geom_TrimmedCurve) TC1 = Handle(Geom_TrimmedCurve)::DownCast(TC->BasisCurve());
if (!TC1.IsNull()) {
BC = Handle(Geom_BSplineCurve)::DownCast(TC1->BasisCurve());
}
}
if (!BC.IsNull()) {
MaxNbPoles = Max(MaxNbPoles,BC->NbPoles());
}
}
aSeq.Append(C);
}
// prepare array of points for creation bspline surface
// size of this array: by U parameter - number of curves,
// by V parameter - determ using MaxNbPoles but it's
// value must be between 21(min) and 101(max)
int nbc = aSeq.Length();
int nbp = Max(21, 2*MaxNbPoles-1);
// commented for Mantis issue 0021541
//if (nbp > 101) nbp = 101;
TColgp_Array2OfPnt Points (1, nbc, 1, nbp);
int ic = 1;
for (; ic <= nbc; ic++) {
Handle(Geom_Curve) C = aSeq.Value(ic);
double fp = C->FirstParameter();
double lp = C->LastParameter();
double dp = (lp-fp)/(nbp-1);
int j = 0;
gp_Pnt P;
for (; j < nbp; j++) {
C->D0(fp+dp*j, P);
Points.SetValue(ic, j+1, P);
}
}
GeomAPI_PointsToBSplineSurface PTB (Points, mindeg, maxdeg, GeomAbs_C2, tol3d);
Handle(Geom_BSplineSurface) BS = PTB.Surface();
BRepBuilderAPI_MakeFace BB (BS, Precision::Confusion());
TopoDS_Face NewF = BB.Face();
Handle(ShapeFix_Face) sff = new ShapeFix_Face (NewF);
sff->Perform();
sff->FixOrientation();
aShape = sff->Face();
}
}
else if( aFunction->GetType() == FILLING_ON_CONSTRAINTS )
{
BRepOffsetAPI_MakeFilling MakeFilling;
Handle(TColStd_HSequenceOfTransient) aConstraints = IF.GetShapes();
TopoDS_Edge E;
TopoDS_Face F;
for( unsigned int ind = 1; ind <= aConstraints->Length(); ind++ ) {
Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast( aConstraints->Value(ind) );
if( !aRefShape->GetValue().IsNull() && aRefShape->GetValue().ShapeType() == TopAbs_EDGE )
E = TopoDS::Edge(aRefShape->GetValue() );
else {
Standard_RangeError::Raise("Wrong parameters");
return 0;
}
Handle(GEOM_Function) aRefFaceShape = Handle(GEOM_Function)::DownCast( aConstraints->Value(ind+1) );
if( !aRefFaceShape->GetValue().IsNull() && aRefFaceShape->GetValue().ShapeType() == TopAbs_FACE ) {
F = TopoDS::Face( aRefFaceShape->GetValue() );
MakeFilling.Add( E, F, GeomAbs_G1 );
ind++;
}
else
MakeFilling.Add( E, GeomAbs_C0 );
}
MakeFilling.Build();
if( !MakeFilling.IsDone() )
{
Standard_RangeError::Raise("filling on constraints failed");
return 0;
}
aShape = TopoDS::Face( MakeFilling.Shape() );
}
/* We test the validity of resulting shape */
@ -351,6 +391,12 @@ GetCreationInformation(std::string& theOperationName,
AddParam( theParams, "Approximation", aCI.GetApprox() );
break;
}
case FILLING_ON_CONSTRAINTS:
{
theOperationName = "FACE";
AddParam( theParams, "Edges/Faces", aCI.GetShapes() );
break;
}
default:
return false;
}

View File

@ -34,11 +34,13 @@
#include "GEOMImpl_VectorDriver.hxx"
#include "GEOMImpl_ShapeDriver.hxx"
#include "GEOMImpl_GlueDriver.hxx"
#include "GEOMImpl_FillingDriver.hxx"
#include "GEOMImpl_IVector.hxx"
#include "GEOMImpl_IShapes.hxx"
#include "GEOMImpl_IShapeExtend.hxx"
#include "GEOMImpl_IGlue.hxx"
#include "GEOMImpl_IFilling.hxx"
#include "GEOMImpl_Block6Explorer.hxx"
#include "GEOMImpl_IHealingOperations.hxx"
@ -677,6 +679,103 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
return aShape;
}
//=============================================================================
/*!
* MakeFaceWithConstraints
*/
//=============================================================================
Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWithConstraints
(std::list<Handle(GEOM_Object)> theConstraints)
{
SetErrorCode(KO);
//Add a new object
Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FILLING);
//Add a new function
Handle(GEOM_Function) aFunction =
aShape->AddFunction(GEOMImpl_FillingDriver::GetID(), FILLING_ON_CONSTRAINTS);
if (aFunction.IsNull()) return NULL;
//Check if the function is set correctly
if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL;
GEOMImpl_IFilling aCI (aFunction);
Handle(TColStd_HSequenceOfTransient) aConstraints = new TColStd_HSequenceOfTransient;
// Shapes
std::list<Handle(GEOM_Object)>::iterator it = theConstraints.begin();
while (it != theConstraints.end()) {
Handle(GEOM_Object) anObject = (*it);
if( anObject.IsNull() || anObject->GetValue().ShapeType() != TopAbs_EDGE ) {
SetErrorCode("NULL argument edge for the constraint creation");
return NULL;
}
Handle(GEOM_Function) aRefSh = anObject->GetLastFunction();
aConstraints->Append(aRefSh);
it++;
if( it != theConstraints.end() ) {
Handle(GEOM_Object) aFace = (*it);
if( aFace.IsNull() ) {
it++;
continue;
}
if( aFace->GetValue().ShapeType() != TopAbs_FACE)
continue;
if( IsSubShapeBelongsTo( anObject, -1, aFace, -1 ) ) {
aRefSh = aFace->GetLastFunction();
aConstraints->Append(aRefSh);
it++;
}
else {
SetErrorCode("Face is NULL or not connected to the Edge");
return NULL;
}
}
}
aCI.SetShapes( aConstraints );
//Compute the shape
Standard_Boolean isWarning = Standard_False;
try {
OCC_CATCH_SIGNALS;
if (!GetSolver()->ComputeFunction(aFunction)) {
SetErrorCode("Shape driver failed");
return NULL;
}
}
catch (Standard_Failure) {
Handle(Standard_Failure) aFail = Standard_Failure::Caught();
SetErrorCode(aFail->GetMessageString());
// to provide warning
if (!aFunction->GetValue().IsNull()) {
isWarning = Standard_True;
} else {
return NULL;
}
}
//Make a Python command
GEOM::TPythonDump pd (aFunction);
pd << aShape << " = geompy.MakeFaceWithConstraints([";
// Constraints
it = theConstraints.begin();
if (it != theConstraints.end() ) {
pd << (*it++);
while (it != theConstraints.end()) {
Handle(GEOM_Object) anObject = (*it++);
if( !anObject.IsNull() )
pd << ", " << anObject;
}
}
pd << "])";
// to provide warning
if (!isWarning) SetErrorCode(OK);
return aShape;
}
//=============================================================================
/*!
* MakeShell
@ -1940,6 +2039,39 @@ TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(G
return aTypeName;
}
//=============================================================================
/*!
* IsSubShapeBelongsTo
*/
//=============================================================================
Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Object) theSubObject,
const Standard_Integer theSubObjectIndex,
Handle(GEOM_Object) theObject,
const Standard_Integer theObjectIndex)
{
if( theObject.IsNull() || theSubObject.IsNull() )
return false;
TopoDS_Shape shape = theObject->GetValue();
TopoDS_Shape subShape = theSubObject->GetValue();
if( shape.IsNull() || subShape.IsNull() )
return false;
TopTools_IndexedMapOfShape anIndices;
if( theObjectIndex > 0 ) {
TopExp::MapShapes( shape, anIndices );
shape = anIndices.FindKey(theObjectIndex);
}
if( theSubObjectIndex > 0 ) {
TopExp::MapShapes( subShape, anIndices );
subShape = anIndices.FindKey(theSubObjectIndex);
}
TopExp::MapShapes( shape, anIndices );
return anIndices.Contains( subShape );
}
//=============================================================================
/*!
* NumberOfSubShapes

View File

@ -88,6 +88,8 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations
Standard_EXPORT Handle(GEOM_Object) MakeFaceFromSurface
(Handle(GEOM_Object) theFace,
Handle(GEOM_Object) theWire);
Standard_EXPORT Handle(GEOM_Object) MakeFaceWithConstraints (std::list<Handle(GEOM_Object)> theConstraints);
Standard_EXPORT Handle(GEOM_Object) MakeShell (std::list<Handle(GEOM_Object)> theShapes);
@ -160,6 +162,11 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations
Standard_EXPORT TCollection_AsciiString GetShapeTypeString (Handle(GEOM_Object) theShape);
Standard_EXPORT Standard_Boolean IsSubShapeBelongsTo(Handle(GEOM_Object) theSubObject,
const Standard_Integer theSubObjectIndex,
Handle(GEOM_Object) theObject,
const Standard_Integer theObjectIndex);
Standard_EXPORT Standard_Integer NumberOfSubShapes (Handle(GEOM_Object) theShape,
const Standard_Integer theShapeType);

View File

@ -331,6 +331,7 @@
#define DIVIDE_EDGE_BY_POINT 13
#define BASIC_FILLING 1
#define FILLING_ON_CONSTRAINTS 2
#define GLUE_FACES 1
#define GLUE_FACES_BY_LIST 2

View File

@ -279,6 +279,37 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeFaceFromSurface
return GetObject(anObject);
}
//=============================================================================
/*!
* MakeFaceWithConstraints
*/
//=============================================================================
GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeFaceWithConstraints
(const GEOM::ListOfGO& theConstraints)
{
GEOM::GEOM_Object_var aGEOMObject;
//Set a not done flag
GetOperations()->SetNotDone();
//Get the shapes
std::list<Handle(GEOM_Object)> aConstraints;
for( int ind = 0; ind < theConstraints.length(); ind++ ) {
Handle(GEOM_Object) anObject = GetObjectImpl( theConstraints[ind] );
aConstraints.push_back(anObject);
}
// Make Face
Handle(GEOM_Object) anObject =
GetOperations()->MakeFaceWithConstraints( aConstraints );
// enable warning status
if (anObject.IsNull())
return aGEOMObject._retn();
return GetObject(anObject);
}
//=============================================================================
/*!
* MakeShell
@ -976,6 +1007,25 @@ char* GEOM_IShapesOperations_i::GetShapeTypeString (GEOM::GEOM_Object_ptr theSha
return CORBA::string_dup(aDescription.ToCString());
}
//=============================================================================
/*!
* IsSubShapeBelongsTo
*/
//=============================================================================
CORBA::Boolean GEOM_IShapesOperations_i::IsSubShapeBelongsTo( const GEOM::GEOM_Object_ptr theSubObject,
const CORBA::Long theSubObjectIndex,
const GEOM::GEOM_Object_ptr theObject,
const CORBA::Long theObjectIndex)
{
Handle(GEOM_Object) aSubObject = GetObjectImpl( theSubObject );
Handle(GEOM_Object) anObject = GetObjectImpl( theObject );
if( anObject.IsNull() || aSubObject.IsNull() )
return false;
// Get parameters
return GetOperations()->IsSubShapeBelongsTo( aSubObject, theSubObjectIndex, anObject, theObjectIndex );
}
//=============================================================================
/*!
* NumberOfFaces

View File

@ -67,6 +67,8 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i :
GEOM::GEOM_Object_ptr MakeFaceFromSurface(GEOM::GEOM_Object_ptr theFace,
GEOM::GEOM_Object_ptr theWire);
GEOM::GEOM_Object_ptr MakeFaceWithConstraints (const GEOM::ListOfGO& theConstraints);
GEOM::GEOM_Object_ptr MakeShell (const GEOM::ListOfGO& theFacesAndShells);
GEOM::GEOM_Object_ptr MakeSolidShell (GEOM::GEOM_Object_ptr theShell);
@ -144,6 +146,11 @@ class GEOM_I_EXPORT GEOM_IShapesOperations_i :
char* GetShapeTypeString (GEOM::GEOM_Object_ptr theShape);
CORBA::Boolean IsSubShapeBelongsTo( const GEOM::GEOM_Object_ptr theSubobject,
const CORBA::Long theSubObjectIndex,
const GEOM::GEOM_Object_ptr theObject,
const CORBA::Long theObjectIndex );
CORBA::Long NumberOfFaces (GEOM::GEOM_Object_ptr theShape);
CORBA::Long NumberOfEdges (GEOM::GEOM_Object_ptr theShape);
CORBA::Long NumberOfSubShapes (GEOM::GEOM_Object_ptr theShape,

View File

@ -2274,6 +2274,24 @@ GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeFaceWires (GEOM::GEOM_List_ptr theWires
return NULL;
}
//=============================================================================
// MakeFaceWithConstraints:
//=============================================================================
GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeFaceWithConstraints (GEOM::GEOM_List_ptr theConstraints)
{
beginService( " GEOM_Superv_i::MakeFaceWithConstraints" );
MESSAGE("GEOM_Superv_i::MakeFaceWithConstraints");
if (GEOM_List_i<GEOM::ListOfGO>* aConstraints =
dynamic_cast<GEOM_List_i<GEOM::ListOfGO>*>(GetServant(theConstraints, myPOA).in())) {
getShapesOp();
GEOM::GEOM_Object_ptr anObj = myShapesOp->MakeFaceWithConstraints(aConstraints->GetList());
endService( " GEOM_Superv_i::MakeFaceWithConstraints" );
return anObj;
}
endService( " GEOM_Superv_i::MakeFaceWithConstraints" );
return NULL;
}
//=============================================================================
// MakeShell:
//=============================================================================

View File

@ -503,6 +503,7 @@ public:
CORBA::Boolean isPlanarWanted);
GEOM::GEOM_Object_ptr MakeFaceWires (GEOM::GEOM_List_ptr theWires,
CORBA::Boolean isPlanarWanted);
GEOM::GEOM_Object_ptr MakeFaceWithConstraints (GEOM::GEOM_List_ptr theConstraints);
GEOM::GEOM_Object_ptr MakeShell (GEOM::GEOM_List_ptr theFacesAndShells);
GEOM::GEOM_Object_ptr MakeSolidShell (GEOM::GEOM_Object_ptr theShell);
GEOM::GEOM_Object_ptr MakeSolidShells (GEOM::GEOM_List_ptr theShells);

View File

@ -4555,6 +4555,30 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
RaiseIfFailed("MakeFaceFromSurface", self.ShapesOp)
self._autoPublish(anObj, theName, "face")
return anObj
@ManageTransactions("ShapesOp")
def MakeFaceWithConstraints(self, theConstraints, theName=None):
"""
Create a face on the given constraints.
Parameters:
theConstraints List of constraints.
Each constraint is a couple (Edge, Face),
where Edge is an Edge of closed Wire
and Face is a Face connected to this Edge.
theName Object name; when specified, this parameter is used
for result publication in the study. Otherwise, if automatic
publication is switched on, default value is used for result name.
Returns:
New GEOM.GEOM_Object, containing the created face.
"""
# Example: see GEOM_TestAll.py
anObj = self.ShapesOp.MakeFaceWithConstraints(theConstraints)
if anObj is None:
RaiseIfFailed("MakeFaceWithConstraints", self.ShapesOp)
self._autoPublish(anObj, theName, "face")
return anObj
## Create a shell from the set of faces and shells.
# @param theFacesAndShells List of faces and/or shells.