[bos #40618] [CEA] Offset/Thickness Feature.

This commit is contained in:
jfa 2024-08-14 01:26:42 +01:00
parent fbbd6a9e07
commit 2447da69cc
19 changed files with 479 additions and 138 deletions

View File

@ -13,14 +13,17 @@ box = geompy.MakeBox(20, 20, 20, 200, 200, 200)
# create a new object as offset of the given object
offset = geompy.MakeOffset(box, 70.)
offset2 = geompy.MakeOffsetIntersectionJoin(box, 70.)
offset3 = geompy.MakeOffsetPartial(box, [13, 33], 70.)
# add objects in the study
id_box = geompy.addToStudy(box, "Box")
id_offset = geompy.addToStudy(offset, "Offset")
id_offset2 = geompy.addToStudy(offset2, "Offset_intersection_join")
id_offset3 = geompy.addToStudy(offset3, "Offset_Partial")
# display the results
gg.createAndDisplayGO(id_box)
gg.setDisplayMode(id_box,1)
gg.createAndDisplayGO(id_offset)
gg.createAndDisplayGO(id_offset2)
gg.createAndDisplayGO(id_offset3)

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -5,6 +5,10 @@
\n To produce an <b>Offset Surface</b> in the <b>Main Menu</b> select
<b>Operations - > Transformation - > Offset Surface</b>
\n There are 2 algorithms for creation of an \b Offset.
\n Firstly, you can offset all faces of selected shape(s) to the same value.
\n This operation translates each point of an \b Object (a set of
Objects) along a local normal by a given \b Offset distance (signed
number, negative value meaning inner offset). Gaps between translated
@ -13,12 +17,12 @@ adjacent surfaces are filled in either of two ways:
- else the surfaces are extended and intersected, so that sharp edges
are preserved.
\n \b Offset operation is applicable to faces, shells and solids.
\n \ref restore_presentation_parameters_page "Advanced options".
\image html transformation11.png
\n <b>Arguments:</b> Name + Object(s) (face(s), shell(s), solid(s)) + Offset value.
\n The \b Result will be a \b GEOM_Object.
\n \ref restore_presentation_parameters_page "Advanced options".
\n <b>Example:</b>
\image html offsetsn.png "The box and its offset surface (Join by pipes activated)"
@ -27,11 +31,27 @@ adjacent surfaces are filled in either of two ways:
- Gaps filled by pipes: <em>geompy.MakeOffset(Shape, Offset),</em>
- Gaps filled by intersection: <em>geompy.MakeOffsetIntersectionJoin(Shape, Offset),</em>
where Shape is a shape(s) which has to be an offset, Offset is a value of
where \b Shape is a shape(s) which has to be an offset, \b Offset is a value of
the offset.
\n <b>Arguments:</b> Name + Object (face(s), shell(s), solid(s)) +
Offset value.
\n Secondly, you can offset only selected faces of the shape to the given value,
other faces will stay at their initial places,
but could be extended to join with offset faces.
Gaps between adjacent surfaces are filled by intersection of extended surfaces.
\image html transformation11a.png
\n <b>Arguments:</b> Name + Object (shell or solid) +
Face(s) of the object + Offset value.
\n The \b Result will be a \b GEOM_Object.
\n \ref restore_presentation_parameters_page "Advanced options".
\n <b>TUI Command:</b>
- <em>geompy.MakeOffsetPartial(Shape, ListOfFacesIDs, Offset),</em>
where \b Shape is a shape(s) which has to be an offset,
\b ListOfFacesIDs is a list of integer IDs of sub-faces and
\b Offset is a value of the offset.
Our <b>TUI Scripts</b> provide you with useful examples of the use of
\ref tui_offset "Transformation Operations".

View File

@ -1345,6 +1345,19 @@ module GEOM
in double theOffset,
in boolean theJoinByPipes);
/*!
* \brief Create new object as offset of the given one.
* Only indexed faces are offset, others keep they original location.
* \param theObject The base object for the offset.
* \param theFacesIDs The list of face IDs indicating faces to be offset.
* \param theOffset Offset value.
* \param theJoinByPipes To join offset surfaces by pipes or by intersection.
* \return New GEOM_Object, containing the offset object.
*/
GEOM_Object OffsetShapePartialCopy (in GEOM_Object theObject,
in ListOfLong theFacesIDs,
in double theOffset);
/*!
* \brief Create new object as projection of the given one on a 2D surface.
* \param theSource The source object for the projection. It can be a point, edge or wire.

View File

@ -132,6 +132,7 @@ SET( _res_files
multitranslationsimple.png
normale.png
offset.png
offset_partial.png
projection.png
projection_on_edge.png
projection_on_wire.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 870 B

View File

@ -796,6 +796,23 @@ QString GEOMBase::GetName( GEOM::GEOM_Object_ptr object )
return name;
}
//=======================================================================
// function : GetName()
// purpose : Get name of objects
//=======================================================================
QString GEOMBase::GetName( const QList<GEOM::GeomObjPtr>& objects )
{
QString name;
int nbSel = objects.count();
if (nbSel == 1)
name = GEOMBase::GetName( objects[0].get() );
else if (nbSel > 1)
name = QObject::tr("%1_objects").arg( nbSel );
return name;
}
//=======================================================================
// function : IsShape()
// purpose : Return TRUE if object is valid and has shape

View File

@ -122,6 +122,7 @@ public :
/* Gets name of object */
static QString GetName( GEOM::GEOM_Object_ptr object );
static QString GetName( const QList<GEOM::GeomObjPtr>& objects );
/* Check if object has shape */
static bool IsShape( GEOM::GEOM_Object_ptr object );

View File

@ -451,6 +451,10 @@
<source>ICON_DLG_OFFSET</source>
<translation>offset.png</translation>
</message>
<message>
<source>ICON_DLG_OFFSET_PARTIAL</source>
<translation>offset_partial.png</translation>
</message>
<message>
<source>ICON_DLG_PROJECTION_ON_FACE</source>
<translation>projection.png</translation>

View File

@ -42,28 +42,6 @@
namespace
{
//=======================================================================
//function : ConvertShapesToIndices
//purpose : Convert sub-shapes of shapes to sequence of indices
//=======================================================================
Handle(TColStd_HArray1OfInteger) ConvertShapesToIndices(const TopoDS_Shape& theShape,
const TopTools_ListOfShape& theShapes)
{
Handle(TColStd_HArray1OfInteger) aSeqOfIDs = new TColStd_HArray1OfInteger(1, theShapes.Size());
TopTools_IndexedMapOfShape anIndices;
TopExp::MapShapes(theShape, anIndices);
TopTools_ListIteratorOfListOfShape itSub(theShapes);
for (int index = 1; itSub.More(); itSub.Next(), ++index)
{
int id = anIndices.FindIndex(itSub.Value());
aSeqOfIDs->SetValue(index, id);
}
return aSeqOfIDs;
}
//=======================================================================
//function : ConvertShapesToIndices
//purpose : Convert list of pair shapes to sequence of indices
@ -203,6 +181,8 @@ Standard_Real GEOMImpl_ConformityDriver::updateTolerance(const TopoDS_Shape& the
case TopAbs_FACE:
aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value()));
break;
default:
break;
}
aTolerance = Min(aTolerance, aCurTolerance);
}
@ -228,6 +208,8 @@ Standard_Real GEOMImpl_ConformityDriver::updateTolerance(const TopoDS_Shape& the
case TopAbs_FACE:
aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value()));
break;
default:
break;
}
aResTol = Max(aResTol, aCurTolerance);
}

View File

@ -1090,10 +1090,11 @@ GEOMImpl_ITransformOperations::OffsetShape (Handle(GEOM_Object) theObject,
* OffsetShapeCopy
*/
//=============================================================================
Handle(GEOM_Object)
GEOMImpl_ITransformOperations::OffsetShapeCopy( Handle(GEOM_Object) theObject,
double theOffset,
bool theJoinByPipes)
Handle(GEOM_Object) GEOMImpl_ITransformOperations::OffsetShapeCopy
(Handle(GEOM_Object) theObject,
double theOffset,
bool theJoinByPipes,
const Handle(TColStd_HArray1OfInteger)& theFacesIDs)
{
SetErrorCode(KO);
@ -1118,6 +1119,10 @@ GEOMImpl_ITransformOperations::OffsetShapeCopy( Handle(GEOM_Object) theObject,
aTI.SetValue( theOffset );
aTI.SetJoinByPipes( theJoinByPipes );
if (!theFacesIDs.IsNull()) {
aTI.SetFaceIDs(theFacesIDs);
}
//Compute the offset
try {
OCC_CATCH_SIGNALS;
@ -1132,18 +1137,31 @@ GEOMImpl_ITransformOperations::OffsetShapeCopy( Handle(GEOM_Object) theObject,
}
//Make a Python command
if (theJoinByPipes)
GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeOffset("
<< theObject << ", " << theOffset << ")";
else
GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeOffsetIntersectionJoin("
<< theObject << ", " << theOffset << ")";
if (theFacesIDs.IsNull()) {
if (theJoinByPipes)
GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeOffset("
<< theObject << ", " << theOffset << ")";
else
GEOM::TPythonDump(aFunction) << aCopy << " = geompy.MakeOffsetIntersectionJoin("
<< theObject << ", " << theOffset << ")";
}
else {
GEOM::TPythonDump pd (aFunction);
pd << aCopy << " = geompy.MakeOffsetPartial("
<< theObject << ", [";
// Dump faces IDs.
for (Standard_Integer i = theFacesIDs->Lower(); i <= theFacesIDs->Upper(); ++i) {
pd << theFacesIDs->Value(i) << ((i == theFacesIDs->Upper()) ? "" : ", ");
}
pd << "], " << theOffset << ")";
}
SetErrorCode(OK);
return aCopy;
}
//=============================================================================
/*!
* ProjectShapeCopy

View File

@ -108,9 +108,11 @@ class GEOMImpl_ITransformOperations : public GEOM_IOperations
double theOffset,
bool theJoinByPipes);
Standard_EXPORT Handle(GEOM_Object) OffsetShapeCopy (Handle(GEOM_Object) theObject,
double theOffset,
bool theJoinByPipes);
Standard_EXPORT Handle(GEOM_Object) OffsetShapeCopy
(Handle(GEOM_Object) theObject,
double theOffset,
bool theJoinByPipes,
const Handle(TColStd_HArray1OfInteger)& theFacesIDs = NULL);
Standard_EXPORT Handle(GEOM_Object) ProjectShapeCopy (Handle(GEOM_Object) theSource,
Handle(GEOM_Object) theTarget);

View File

@ -28,12 +28,13 @@
#include <GEOM_Function.hxx>
#include <GEOMUtils.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepOffsetAPI_MakeOffsetShape.hxx>
#include <BRepOffsetAPI_MakeThickSolid.hxx>
#include <TopoDS_Shape.hxx>
#include <TopAbs.hxx>
#include <TopExp.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <Precision.hxx>
#include <Standard_ConstructionError.hxx>
#include <StdFail_NotDone.hxx>
@ -88,24 +89,79 @@ Standard_Integer GEOMImpl_OffsetDriver::Execute(Handle(TFunction_Logbook)& log)
if ( aType == OFFSET_SHAPE || aType == OFFSET_SHAPE_COPY )
{
BRepOffsetAPI_MakeOffsetShape MO;
BRepOffset_Mode aMode = BRepOffset_Skin;
Standard_Boolean anIntersection = Standard_False, aSelfInter = Standard_False;
MO.PerformByJoin( aShapeBase,
aCI.GetValue(),
aTol,
aMode,
anIntersection,
aSelfInter,
aCI.GetJoinByPipes() ? GeomAbs_Arc : GeomAbs_Intersection );
Standard_Boolean anIntersection = Standard_False;
Standard_Boolean aSelfInter = Standard_False;
if ( MO.IsDone() ) {
aShape = MO.Shape();
if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) )
Standard_ConstructionError::Raise("Boolean operation aborted : non valid shape result");
Handle(TColStd_HArray1OfInteger) aFacesIDs = aCI.GetFaceIDs();
if (aFacesIDs.IsNull() || aFacesIDs->Length() < 1) {
// Offset entire shape (all faces) with the same offset value
BRepOffsetAPI_MakeOffsetShape MO;
MO.PerformByJoin( aShapeBase,
anOffset,
aTol,
aMode,
anIntersection,
aSelfInter,
aCI.GetJoinByPipes() ? GeomAbs_Arc : GeomAbs_Intersection );
if ( MO.IsDone() ) {
aShape = MO.Shape();
if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) )
Standard_ConstructionError::Raise("Offset aborted : non valid shape result");
}
else {
StdFail_NotDone::Raise("Offset construction failed");
}
}
else {
StdFail_NotDone::Raise("Offset construction failed");
// Offset selected faces of main shape by given value, other faces by 0
BRepOffset_MakeOffset aMakeOffset;
aMakeOffset.Initialize(aShapeBase,
anOffset, // set offset on all faces to anOffset
aTol,
aMode,
anIntersection,
aSelfInter,
aCI.GetJoinByPipes() ? GeomAbs_Arc : GeomAbs_Intersection,
Standard_False);
// put selected faces into a map
TopTools_MapOfShape aMapFaces;
TopTools_IndexedMapOfShape anIndices;
TopExp::MapShapes(aShapeBase, anIndices);
Standard_Integer aNbShapes = anIndices.Extent();
for (Standard_Integer i = aFacesIDs->Lower(); i <= aFacesIDs->Upper(); ++i) {
const Standard_Integer anIndex = aFacesIDs->Value(i);
if (anIndex < 1 || anIndex > aNbShapes) {
Standard_ConstructionError::Raise("Offset aborted : Invalid face index given");
}
const TopoDS_Shape &aFace = anIndices.FindKey(anIndex);
if (aFace.ShapeType() != TopAbs_FACE) {
Standard_ConstructionError::Raise("Offset aborted : Shape by index is not a face");
}
aMapFaces.Add(aFace);
}
// set offset on non-selected faces to zero
TopExp_Explorer anExp (aShapeBase, TopAbs_FACE);
for (; anExp.More(); anExp.Next()) {
const TopoDS_Shape &aFace = anExp.Current();
if (!aMapFaces.Contains(aFace)) {
aMakeOffset.SetOffsetOnFace(TopoDS::Face(aFace), 0.0);
}
}
// perform offset operation
aMakeOffset.MakeOffsetShape();
if ( aMakeOffset.IsDone() ) {
aShape = aMakeOffset.Shape();
if ( !GEOMUtils::CheckShape(aShape, true) && !GEOMUtils::FixShapeTolerance(aShape) )
Standard_ConstructionError::Raise("Offset aborted : non valid shape result");
}
else {
StdFail_NotDone::Raise("Offset construction failed");
}
}
}
else if (aType == OFFSET_THICKENING || aType == OFFSET_THICKENING_COPY)
@ -216,6 +272,12 @@ GetCreationInformation(std::string& theOperationName,
theOperationName = "OFFSET";
AddParam( theParams, "Object", aCI.GetShape() );
AddParam( theParams, "Offset", aCI.GetValue() );
{
Handle(TColStd_HArray1OfInteger) aFacesIDs = aCI.GetFaceIDs();
if (!aFacesIDs.IsNull()) {
AddParam(theParams, "Faces IDs", aFacesIDs);
}
}
break;
case OFFSET_THICKENING:
case OFFSET_THICKENING_COPY:

View File

@ -1366,8 +1366,8 @@ GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i:
std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects>::iterator anIter(aSelfInters.begin());
for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
{
aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
aSeq[i].first = GetObject((*anIter).first);
aSeq[i].second = GetObject((*anIter).second);
}
return aSeq._retn();
@ -1404,8 +1404,8 @@ GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i:
std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects>::iterator anIter(aSelfInterf.begin());
for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
{
aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
aSeq[i].first = GetObject((*anIter).first);
aSeq[i].second = GetObject((*anIter).second);
}
return aSeq._retn();
@ -1471,8 +1471,8 @@ GEOM::GEOM_IMeasureOperations::SequenceOfPairOfShape* GEOM_IMeasureOperations_i:
std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects>::iterator anIter(aDistantS.begin());
for (Standard_Integer i = 0; i < aLength; i++, ++anIter)
{
aSeq[i].first = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).first));
aSeq[i].second = GetObject(Handle(::GEOM_Object)::DownCast((*anIter).second));
aSeq[i].first = GetObject((*anIter).first);
aSeq[i].second = GetObject((*anIter).second);
}
return aSeq._retn();
@ -1502,8 +1502,8 @@ GEOM::GEOM_IMeasureOperations::CheckResults* GEOM_IMeasureOperations_i::CheckCon
for (Standard_Integer i = 0; i < aLength; i++, ++anIntIt)
{
aRes[i].type = (*anIntIt).TypeOfCheck;
aRes[i].failedShapes.first = GetObject(Handle(::GEOM_Object)::DownCast((*anIntIt).FailedShapes.first));
aRes[i].failedShapes.second = GetObject(Handle(::GEOM_Object)::DownCast((*anIntIt).FailedShapes.second));
aRes[i].failedShapes.first = GetObject((*anIntIt).FailedShapes.first);
aRes[i].failedShapes.second = GetObject((*anIntIt).FailedShapes.second);
}
return aRes._retn();
@ -1530,7 +1530,7 @@ CORBA::Double GEOM_IMeasureOperations_i::UpdateTolerance(GEOM::GEOM_Object_ptr t
void GEOM_IMeasureOperations_i::ConvertToList(const GEOM::GEOM_IMeasureOperations::CheckResults& theResuts,
std::list<GEOMImpl_IMeasureOperations::FailedChecks>& theListOfResults)
{
for (Standard_Integer i = 0; i < theResuts.length(); ++i)
for (size_t i = 0; i < theResuts.length(); ++i)
{
GEOMImpl_IMeasureOperations::FailedChecks aCheck;
aCheck.TypeOfCheck = theResuts[i].type;

View File

@ -668,6 +668,47 @@ GEOM_ITransformOperations_i::OffsetShapeCopy (GEOM::GEOM_Object_ptr theObject,
return GetObject(anObject);
}
//=============================================================================
/*!
* OffsetShapePartialCopy
*/
//=============================================================================
GEOM::GEOM_Object_ptr
GEOM_ITransformOperations_i::OffsetShapePartialCopy (GEOM::GEOM_Object_ptr theObject,
const GEOM::ListOfLong& theFacesIDs,
CORBA::Double theOffset)
{
GEOM::GEOM_Object_var aGEOMObject;
//Set a not done flag
GetOperations()->SetNotDone();
//Get the basic object
Handle(::GEOM_Object) aBasicObject = GetObjectImpl(theObject);
if (aBasicObject.IsNull()) return aGEOMObject._retn();
// Get faces IDs.
Handle(TColStd_HArray1OfInteger) aFaceIDs;
Standard_Integer aNbIDs = theFacesIDs.length();
if (aNbIDs > 0) {
aFaceIDs = new TColStd_HArray1OfInteger (1, aNbIDs);
for (Standard_Integer i = 0; i < aNbIDs; i++) {
aFaceIDs->SetValue(i + 1, theFacesIDs[i]);
}
}
// join by pipes mode is not supported in combination with partial offset
bool aJoinByPipes = false;
//Create the offset shape
Handle(::GEOM_Object) anObject =
GetOperations()->OffsetShapeCopy(aBasicObject, theOffset, aJoinByPipes, aFaceIDs);
if (!GetOperations()->IsDone() || anObject.IsNull())
return aGEOMObject._retn();
return GetObject(anObject);
}
//=============================================================================
/*!
* ProjectShapeCopy

View File

@ -142,6 +142,10 @@ class GEOM_I_EXPORT GEOM_ITransformOperations_i :
CORBA::Double theOffset,
CORBA::Boolean theJoinByPipes);
GEOM::GEOM_Object_ptr OffsetShapePartialCopy (GEOM::GEOM_Object_ptr theObject,
const GEOM::ListOfLong& theFacesIDs,
CORBA::Double theOffset);
GEOM::GEOM_Object_ptr ProjectShapeCopy (GEOM::GEOM_Object_ptr theSource,
GEOM::GEOM_Object_ptr theTarget);

View File

@ -9623,6 +9623,51 @@ class geomBuilder(GEOM._objref_GEOM_Gen):
self._autoPublish(anObj, theName, "offset")
return anObj
## Create new object as partial offset of the given one.
# Only indexed faces are offset, others keep they original location.
# Gap between adjacent offset surfaces is filled
# by extending and intersecting them.
# @param theObject The base object for the offset.
# @param theFacesIDs The list of face IDs indicating faces to be offset.
# @param theOffset Offset value.
# @param 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.
#
# @return New GEOM.GEOM_Object, containing the offset object.
#
# @ref tui_offset "Example"
@ManageTransactions("TrsfOp")
def MakeOffsetPartial(self, theObject, theFacesIDs, theOffset, theName=None):
"""
Create new object as partial offset of the given one.
Only indexed faces are offset, others keep they original location.
Gap between adjacent offset surfaces is filled
by extending and intersecting them.
Parameters:
theObject The base object for the offset.
theFacesIDs The list of face IDs indicating faces to be offset.
theOffset Offset value.
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 offset object.
Example of usage:
box = geompy.MakeBox(20, 20, 20, 200, 200, 200)
# create a new object from the box, offsetting its top and front faces
offset = geompy.MakeOffsetPartial(box, [13, 33], 70.)
"""
theOffset, Parameters = ParseParameters(theOffset)
anObj = self.TrsfOp.OffsetShapePartialCopy(theObject, theFacesIDs, theOffset)
RaiseIfFailed("OffsetShapePartialCopy", self.TrsfOp)
anObj.SetParameters(Parameters)
self._autoPublish(anObj, theName, "offset")
return anObj
## Create new object as projection of the given one on another.
# @param theSource The source object for the projection. It can be a point, edge or wire.
# Edge and wire are acceptable if @a theTarget is a face.

View File

@ -35,6 +35,9 @@
#include <SalomeApp_Application.h>
#include <LightApp_SelectionMgr.h>
#include <TopExp.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
//=================================================================================
// class : TransformationGUI_OffsetDlg()
// purpose : Constructs a TransformationGUI_OffsetDlg which is a child of 'parent', with the
@ -42,31 +45,41 @@
// The dialog will by default be modeless, unless you set 'modal' to
// TRUE to construct a modal dialog.
//=================================================================================
TransformationGUI_OffsetDlg::TransformationGUI_OffsetDlg( GeometryGUI* theGeometryGUI, QWidget* parent,
bool modal, Qt::WindowFlags fl )
: GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl )
TransformationGUI_OffsetDlg::TransformationGUI_OffsetDlg
(GeometryGUI* theGeometryGUI, QWidget* parent,
bool modal, Qt::WindowFlags fl)
: GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl)
{
QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_DLG_OFFSET" ) ) );
QPixmap image1( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_SELECT" ) ) );
SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
QPixmap image1 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_OFFSET")));
QPixmap image2 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_OFFSET_PARTIAL")));
setWindowTitle( tr( "GEOM_OFFSET_TITLE" ) );
setWindowTitle(tr("GEOM_OFFSET_TITLE"));
/***************************************************************/
mainFrame()->GroupConstructors->setTitle( tr( "GEOM_OFFSET" ) );
mainFrame()->RadioButton1->setIcon( image0 );
mainFrame()->RadioButton2->setAttribute( Qt::WA_DeleteOnClose );
mainFrame()->RadioButton2->close();
mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
mainFrame()->GroupConstructors->setTitle(tr("GEOM_OFFSET"));
mainFrame()->RadioButton1->setIcon(image1);
mainFrame()->RadioButton2->setIcon(image2);
mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
mainFrame()->RadioButton3->close();
mainFrame()->RadioButton1->setChecked(true);
GroupPoints = new DlgRef_2Sel1Spin2Check( centralWidget() );
GroupPoints = new DlgRef_1Sel1Spin1Check( centralWidget() );
GroupPoints->GroupBox1->setTitle( tr( "GEOM_ARGUMENTS" ) );
GroupPoints->TextLabel1->setText( tr( "GEOM_OBJECTS" ) );
GroupPoints->TextLabel2->setText( tr( "GEOM_OFFSET" ) );
GroupPoints->TextLabel2->setText( tr( "GEOM_FACES" ) );
GroupPoints->TextLabel3->setText( tr( "GEOM_OFFSET" ) );
GroupPoints->PushButton1->setIcon( image0 );
GroupPoints->PushButton2->setIcon( image0 );
GroupPoints->CheckButton1->setText( tr( "GEOM_JOIN_BY_PIPES" ) );
GroupPoints->CheckButton1->setChecked( true );
GroupPoints->PushButton1->setIcon( image1 );
GroupPoints->CheckButton2->setAttribute( Qt::WA_DeleteOnClose );
GroupPoints->CheckButton2->close();
QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
layout->setMargin( 0 ); layout->setSpacing( 6 );
@ -99,33 +112,76 @@ void TransformationGUI_OffsetDlg::Init()
/* init variables */
myEditCurrentArgument = GroupPoints->LineEdit1;
GroupPoints->LineEdit1->setReadOnly( true );
GroupPoints->LineEdit2->setReadOnly( true );
myObjects.clear();
/* Get setting of step value from file configuration */
double step = 1;
myFaces.clear();
/* min, max, step and decimals for spin boxes & initial values */
double step = 1;
initSpinBox( GroupPoints->SpinBox_DX, COORD_MIN, COORD_MAX, step, "length_precision" );
GroupPoints->SpinBox_DX->setValue( 1e-05 );
mainFrame()->GroupBoxPublish->show();
/* signals and slots connections */
connect( buttonOk(), SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
connect(this, SIGNAL(constructorsClicked(int)),
this, SLOT(ConstructorsClicked(int)));
connect( GroupPoints->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
connect( myGeomGUI->getApp()->selectionMgr(),
SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
connect(GroupPoints->PushButton1, SIGNAL(clicked()),
this, SLOT(SetEditCurrentArgument()));
connect(GroupPoints->PushButton2, SIGNAL(clicked()),
this, SLOT(SetEditCurrentArgument()));
connect( GroupPoints->SpinBox_DX, SIGNAL( valueChanged( double ) ), this, SLOT( ValueChangedInSpinBox() ) );
connect( GroupPoints->CheckButton1, SIGNAL( toggled( bool ) ), this, SLOT( JoinModeChanged() ) );
connect(GroupPoints->SpinBox_DX, SIGNAL(valueChanged(double)),
this, SLOT(ValueChangedInSpinBox()));
connect(GroupPoints->CheckButton1, SIGNAL(toggled(bool)),
this, SLOT(JoinModeChanged()));
initName( tr( "GEOM_OFFSET" ) );
connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
this, SLOT(SelectionIntoArgument()));
globalSelection( GEOM_ALLSHAPES );
resize(100,100);
initName(tr("GEOM_OFFSET"));
ConstructorsClicked(0);
}
//==============================================================================
// function : ConstructorsClicked()
// purpose : Radio button management
//==============================================================================
void TransformationGUI_OffsetDlg::ConstructorsClicked (int constructorId)
{
switch (constructorId) {
case 0:
// disable faces selection
GroupPoints->TextLabel2->hide();
GroupPoints->PushButton2->hide();
GroupPoints->LineEdit2->hide();
// enable joint type
GroupPoints->CheckButton1->show();
break;
case 1:
// enable faces selection
GroupPoints->TextLabel2->show();
GroupPoints->PushButton2->show();
GroupPoints->LineEdit2->show();
// disable joint type
GroupPoints->CheckButton1->hide();
break;
default:
break;
}
qApp->processEvents();
updateGeometry();
resize(minimumSizeHint());
GroupPoints->PushButton1->click();
SelectionIntoArgument();
}
@ -152,6 +208,10 @@ bool TransformationGUI_OffsetDlg::ClickOnApply()
return false;
initName();
// activate selection and connect selection manager
ConstructorsClicked(getConstructorId());
return true;
}
@ -162,13 +222,27 @@ bool TransformationGUI_OffsetDlg::ClickOnApply()
//=================================================================================
void TransformationGUI_OffsetDlg::SelectionIntoArgument()
{
myObjects = getSelected( TopAbs_SHAPE, -1 );
if ( !myObjects.isEmpty() ) {
QString aName = myObjects.count() > 1 ? QString( "%1_objects").arg( myObjects.count() ) : GEOMBase::GetName( myObjects[0].get() );
myEditCurrentArgument->setText( aName );
myEditCurrentArgument->setText("");
if (myEditCurrentArgument == GroupPoints->LineEdit1) {
if (getConstructorId() == 0) {
myObjects = getSelected( TopAbs_SHAPE, -1 );
myEditCurrentArgument->setText(GEOMBase::GetName(myObjects));
}
else if (getConstructorId() == 1) {
myFaces.clear();
GroupPoints->LineEdit2->setText("");
myObjects = getSelected(TopAbs_SHAPE, 1); // only one object allowed
if (!myObjects.isEmpty()) {
myEditCurrentArgument->setText(GEOMBase::GetName(myObjects[0].get()));
GroupPoints->PushButton2->click();
}
}
}
else {
myEditCurrentArgument->setText("");
else if (myEditCurrentArgument == GroupPoints->LineEdit2) {
myFaces.clear();
myFaces = getSelected(TopAbs_FACE, -1);
myEditCurrentArgument->setText(GEOMBase::GetName(myFaces));
}
processPreview();
@ -184,11 +258,20 @@ void TransformationGUI_OffsetDlg::SetEditCurrentArgument()
QPushButton* send = (QPushButton*)sender();
if ( send == GroupPoints->PushButton1 ) {
GroupPoints->PushButton1->setDown(true);
GroupPoints->PushButton2->setDown(false);
myEditCurrentArgument = GroupPoints->LineEdit1;
myEditCurrentArgument->setFocus();
SelectionIntoArgument();
globalSelection(GEOM_ALLSHAPES);
}
else if (send == GroupPoints->PushButton2) {
GroupPoints->PushButton1->setDown(false);
myEditCurrentArgument = GroupPoints->LineEdit2;
globalSelection(); // close local contexts, if any
if (myObjects.size() > 0)
localSelection(myObjects[0].get(), TopAbs_FACE);
}
myEditCurrentArgument->setFocus();
send->setDown(true);
}
@ -210,11 +293,11 @@ void TransformationGUI_OffsetDlg::enterEvent( QEvent* )
void TransformationGUI_OffsetDlg::ActivateThisDialog()
{
GEOMBase_Skeleton::ActivateThisDialog();
connect( myGeomGUI->getApp()->selectionMgr(),
SIGNAL( currentSelectionChanged() ), this, SLOT( SelectionIntoArgument() ) );
globalSelection( GEOM_ALLSHAPES );
myEditCurrentArgument = GroupPoints->LineEdit1;
myEditCurrentArgument->setFocus();
ConstructorsClicked(getConstructorId());
}
@ -243,14 +326,27 @@ GEOM::GEOM_IOperations_ptr TransformationGUI_OffsetDlg::createOperation()
//=================================================================================
bool TransformationGUI_OffsetDlg::isValid( QString& msg )
{
bool ok = GroupPoints->SpinBox_DX->isValid( msg, !IsPreview() ) && !myObjects.isEmpty();
for ( int i = 0; i < myObjects.count() && ok; i++ ) {
GEOM::shape_type aType = myObjects[i]->GetShapeType();
ok = aType == GEOM::FACE || aType == GEOM::SHELL || aType == GEOM::SOLID;
if ( !ok )
msg = tr( "ERROR_SHAPE_TYPE" );
bool isOk = GroupPoints->SpinBox_DX->isValid( msg, !IsPreview() ) && !myObjects.isEmpty();
if (isOk) {
switch (getConstructorId()) {
case 0:
for ( int i = 0; i < myObjects.count() && isOk; i++ ) {
GEOM::shape_type aType = myObjects[i]->GetShapeType();
isOk = aType == GEOM::FACE || aType == GEOM::SHELL || aType == GEOM::SOLID;
if ( !isOk )
msg = tr( "ERROR_SHAPE_TYPE" );
}
break;
case 1:
isOk = myObjects.size() == 1 && !myFaces.isEmpty();
break;
default:
break;
}
}
return ok;
return isOk;
}
//=================================================================================
@ -263,28 +359,59 @@ bool TransformationGUI_OffsetDlg::execute( ObjectList& objects )
GEOM::GEOM_Object_var anObj;
GEOM::GEOM_ITransformOperations_var anOper = GEOM::GEOM_ITransformOperations::_narrow(getOperation());
GEOM::GEOM_ITransformOperations_var anOper =
GEOM::GEOM_ITransformOperations::_narrow(getOperation());
if ( true /*GroupPoints->CheckButton1->isChecked() || IsPreview()*/ ) {
for ( int i = 0; i < myObjects.count(); i++ ) {
anObj = anOper->OffsetShapeCopy( myObjects[i].get(), GetOffset(), GetIsJoinByPipes() );
if ( !anObj->_is_nil() ) {
if(!IsPreview()) {
if (getConstructorId() == 0) {
for (int i = 0; i < myObjects.count(); i++) {
anObj = anOper->OffsetShapeCopy(myObjects[i].get(), GetOffset(), GetIsJoinByPipes());
if (!anObj->_is_nil()) {
if (!IsPreview()) {
anObj->SetParameters(GroupPoints->SpinBox_DX->text().toUtf8().constData());
}
objects.push_back( anObj._retn() );
objects.push_back(anObj._retn());
res = true;
}
}
}
else {
for ( int i = 0; i < myObjects.count(); i++ ) {
anObj = anOper->OffsetShape( myObjects[i].get(), GetOffset(), GetIsJoinByPipes() );
if ( !anObj->_is_nil() )
objects.push_back( anObj._retn() );
else if (getConstructorId() == 1) {
if (myObjects.count() == 1) {
TopoDS_Shape aShape;
if (GEOMBase::GetShape(myObjects[0].get(), aShape)) {
TopTools_IndexedMapOfShape aMainMap;
TopExp::MapShapes(aShape, aMainMap);
QList<int> aListIDs;
for (int i = 0; i < myFaces.count(); i++) {
TopoDS_Shape aFace;
if (GEOMBase::GetShape(myFaces[i].get(), aFace)) {
int anIndex = aMainMap.FindIndex(aFace);
if (anIndex >= 0) {
aListIDs << anIndex;
}
}
}
GEOM::ListOfLong_var aFacesIDsList = new GEOM::ListOfLong();
if (!aListIDs.empty()) {
aFacesIDsList->length(aListIDs.length());
for (int i = 0; i < aListIDs.length(); i++) {
aFacesIDsList[i] = aListIDs[i];
}
}
anObj = anOper->OffsetShapePartialCopy
(myObjects[0].get(), aFacesIDsList, GetOffset());
if (!anObj->_is_nil()) {
if (!IsPreview()) {
anObj->SetParameters(GroupPoints->SpinBox_DX->text().toUtf8().constData());
}
objects.push_back(anObj._retn());
res = true;
}
}
}
}
res = true;
return res;
}
@ -330,7 +457,6 @@ bool TransformationGUI_OffsetDlg::GetIsJoinByPipes() const
void TransformationGUI_OffsetDlg::JoinModeChanged()
{
processPreview();
//mainFrame()->GroupBoxName->setEnabled( GroupPoints->CheckButton1->isChecked() );
}
//=================================================================================

View File

@ -30,14 +30,14 @@
#include "GEOMBase_Skeleton.h"
#include "GEOM_GenericObjPtr.h"
class DlgRef_1Sel1Spin1Check;
class DlgRef_2Sel1Spin2Check;
//=================================================================================
// class : TransformationGUI_OffsetDlg
// purpose :
//=================================================================================
class TransformationGUI_OffsetDlg : public GEOMBase_Skeleton
{
{
Q_OBJECT
public:
@ -52,24 +52,26 @@ protected:
virtual bool execute( ObjectList& );
virtual void restoreSubShapes( SALOMEDS::SObject_ptr );
virtual QList<GEOM::GeomObjPtr> getSourceObjects();
private:
void Init();
void enterEvent( QEvent* );
double GetOffset() const;
bool GetIsJoinByPipes() const;
private:
QList<GEOM::GeomObjPtr> myObjects;
DlgRef_1Sel1Spin1Check* GroupPoints;
QList<GEOM::GeomObjPtr> myFaces;
DlgRef_2Sel1Spin2Check* GroupPoints;
private slots:
void ClickOnOk();
bool ClickOnApply();
void ActivateThisDialog();
void SelectionIntoArgument();
void SetEditCurrentArgument();
void ConstructorsClicked(int);
void ValueChangedInSpinBox();
void JoinModeChanged();
};