mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2024-12-25 17:00:35 +05:00
0022775: [CEA 1091] Add an option on GetNonBlocks to retrieve quadrangular faces defined on C1 edges
This commit is contained in:
parent
48e895f1fa
commit
cbdcb3694d
BIN
doc/salome/gui/GEOM/images/measures10.png
Executable file → Normal file
BIN
doc/salome/gui/GEOM/images/measures10.png
Executable file → Normal file
Binary file not shown.
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 29 KiB |
Binary file not shown.
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 24 KiB |
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 8.4 KiB |
@ -8,7 +8,10 @@ This operation checks whether a shape is a compound of glued blocks.
|
||||
|
||||
To be considered as a compound of blocks, the given shape must satisfy the
|
||||
following conditions:
|
||||
- Each element of the compound should be a Block (6 faces and 12 edges);
|
||||
- Each element of the compound should be a Block (6 quadrangle faces);
|
||||
- Each quadrangle face is a face that has 1 wire with 4 edges. If there are
|
||||
more than 4 edges in a single wire and C1 continuity mode is switched on,
|
||||
a face is quadrangular if it has 4 bounds of C1 continuity.
|
||||
- Blocks can be connected only via an entire quadrangle face or an entire edge;
|
||||
- The compound should be connected;
|
||||
- Each couple of connecting quadrangle faces should be glued.
|
||||
@ -16,8 +19,10 @@ following conditions:
|
||||
|
||||
In this dialog:
|
||||
|
||||
- \b Object - the checked object. \b Selection button allows picking it in the viewer or in the object browser.
|
||||
- \b Errors list informs of possible errors, for example:.
|
||||
- \b Object - the checked object. \b Selection button allows picking it in the viewer or in the object browser.
|
||||
- <b>Use C1 criterion</b> - option that shitches on/off the C1 continuity mode.
|
||||
- <b>Angular Tolerance</b> - angular tolerance to check C1 continuity between neighbor edges in a wire.
|
||||
- \b Errors list informs of possible errors, for example:
|
||||
- Not a block;
|
||||
- Not glued;
|
||||
- Not connected;
|
||||
@ -26,7 +31,7 @@ In this dialog:
|
||||
|
||||
|
||||
\n <b>TUI Command:</b>
|
||||
<em>geompy.CheckCompoundOfBlocks(Compound).</em> Checks if the shape
|
||||
<em>geompy.CheckCompoundOfBlocks(Compound, theIsUseC1 = False, theAngTolerance = 1.e-12).</em> Checks if the shape
|
||||
is a valid compound of blocks. If it is true, then the validity flag
|
||||
is returned, and encountered errors are printed in the python console.
|
||||
|
||||
|
@ -5,24 +5,45 @@
|
||||
|
||||
This operation retrieves all non-block solids and non-quadrangular faces from the selected shape.
|
||||
|
||||
A non-block solid is a solid that does not have 6 faces, or has 6 faces, but some of them are not quadrangular.
|
||||
A block solid is a solid that has 6 quadrangular faces.
|
||||
|
||||
A quadrangular face is a face that has 1 wire with 4 edges. If there are
|
||||
more than 4 edges in a single wire and C1 continuity mode is switched on,
|
||||
a face is quadrangular if it has 4 bounds of C1 continuity.
|
||||
|
||||
All solids and faces from a shape that do not satisfy these conditions are
|
||||
returned by this operation.
|
||||
|
||||
\image html measures2.png
|
||||
|
||||
\b Preview option shows non block solids and faces in the viewer.
|
||||
It is possible to select an \b Object to be explored, to check or uncheck
|
||||
<b>Use C1 criterion</b> option and to set the <b>Angular Tolerance</b>
|
||||
to check C1 continuity between neighbor edges in a wire.
|
||||
|
||||
Press \b Apply or <b>Apply and Close</b> button to publish non block solids and faces in the Object
|
||||
Browser under the processed object. Solids and faces are published separately in two groups.
|
||||
\b Preview option shows non-block solids and non-quadrangular faces in the viewer.
|
||||
|
||||
Press \b Apply or <b>Apply and Close</b> button to publish non-block solids
|
||||
and non-quadrangular faces in the Object Browser under the processed object.
|
||||
Solids and faces are published separately in two groups.
|
||||
|
||||
If no bad sub-shapes have been found, the corresponding warning is shown.
|
||||
|
||||
\image html measures2a.png
|
||||
|
||||
\n <b>TUI Command:</b>
|
||||
<em>geompy.GetNonBlocks(Compound).</em> Returns a tuple of two GEOM_Objects.
|
||||
<em>geompy.GetNonBlocks(theShape, theIsUseC1 = False, theAngTolerance = 1.e-12).</em> \n
|
||||
where \n
|
||||
\em theShape is the shape to explore, \n
|
||||
\em theIsUseC1 is the flag to check if there are 4 bounds on a face
|
||||
taking into account C1 continuity, \n
|
||||
\em theAngTolerance the angular tolerance to check if two neighbor edges are
|
||||
codirectional in the common vertex with this tolerance. This parameter is
|
||||
used only if \em theIsUseC1 is set to True.
|
||||
|
||||
The first object is a group of all non block solids; the second object is a group of all non
|
||||
quadrangular faces.
|
||||
This command returns a tuple of two GEOM_Objects.
|
||||
|
||||
The first object is a group of all non-block solids; the second object is a group
|
||||
of all non-quadrangular faces.
|
||||
|
||||
See also a \ref tui_get_non_blocks_page "TUI example".
|
||||
|
||||
|
@ -2770,10 +2770,14 @@ module GEOM
|
||||
* - The glue between two quadrangle faces should be applied.
|
||||
* \note Single block is also accepted as a valid compound of blocks.
|
||||
* \param theCompound The compound to check.
|
||||
* \param theToleranceC1 the tolerance to check if two neighbor edges are
|
||||
* collinear in the common vertex with this tolerance. Negative
|
||||
* value means that C1 criterion is not used (old implementation).
|
||||
* \param theErrors Structure, containing discovered errors and incriminated sub-shapes.
|
||||
* \return TRUE, if the given shape is a compound of blocks.
|
||||
*/
|
||||
boolean CheckCompoundOfBlocks (in GEOM_Object theCompound,
|
||||
in double theToleranceC1,
|
||||
out BCErrors theErrors);
|
||||
|
||||
/*!
|
||||
@ -2790,12 +2794,17 @@ module GEOM
|
||||
* \brief Retrieve all non blocks solids and faces from a shape.
|
||||
*
|
||||
* \param theShape The shape to explore.
|
||||
* \param theToleranceC1 the tolerance to check if two neighbor edges are
|
||||
* collinear in the common vertex with this tolerance. Negative
|
||||
* value means that C1 criterion is not used (old implementation).
|
||||
* \param theNonQuads Output parameter. Group of all non quadrangular faces.
|
||||
*
|
||||
* \return Group of all non block solids (= not 6 faces, or with 6
|
||||
* faces, but with the presence of non-quadrangular faces).
|
||||
*/
|
||||
GEOM_Object GetNonBlocks (in GEOM_Object theShape, out GEOM_Object theNonQuads);
|
||||
GEOM_Object GetNonBlocks (in GEOM_Object theShape,
|
||||
in double theToleranceC1,
|
||||
out GEOM_Object theNonQuads);
|
||||
|
||||
/*!
|
||||
* \brief Remove all seam and degenerated edges from \a theShape.
|
||||
|
@ -1583,7 +1583,7 @@ bool AdvancedEngine_IOperations::MakePipeTShapePartition(Handle(GEOM_Object) the
|
||||
|
||||
// Last verification: result should be a block
|
||||
std::list<GEOMImpl_IBlocksOperations::BCError> errList;
|
||||
if (!myBlocksOperations->CheckCompoundOfBlocks(Te3,errList)) {
|
||||
if (!myBlocksOperations->CheckCompoundOfBlocks(Te3, -1, errList)) {
|
||||
SetErrorCode("TShape is not a compound of block");
|
||||
return false;
|
||||
}
|
||||
|
@ -28,6 +28,11 @@
|
||||
|
||||
#include <BRep_Tool.hxx>
|
||||
|
||||
#include <Geom_Curve.hxx>
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
|
||||
#include <TopExp.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
|
||||
@ -36,8 +41,10 @@
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Solid.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
|
||||
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
|
||||
#include <TopTools_IndexedMapOfShape.hxx>
|
||||
#include <TopTools_MapOfShape.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
@ -49,6 +56,7 @@
|
||||
BlockFix_CheckTool::BlockFix_CheckTool( )
|
||||
{
|
||||
myHasCheck = Standard_False;
|
||||
myAngTolerance = -1.;
|
||||
myPossibleBlocks.Clear();
|
||||
}
|
||||
|
||||
@ -63,6 +71,17 @@ void BlockFix_CheckTool::SetShape(const TopoDS_Shape& aShape)
|
||||
myPossibleBlocks.Clear();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetAngTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void BlockFix_CheckTool::SetAngTolerance(const Standard_Real theTolerance)
|
||||
{
|
||||
myHasCheck = Standard_False;
|
||||
myAngTolerance = theTolerance;
|
||||
myPossibleBlocks.Clear();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
@ -159,7 +178,6 @@ void BlockFix_CheckTool::Perform()
|
||||
if (nbe < 12)
|
||||
IsBlock = Standard_False;
|
||||
if (nbe > 12) {
|
||||
IsBlock = Standard_False;
|
||||
// check edges unification
|
||||
// creating map of edge faces
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
|
||||
@ -194,9 +212,19 @@ void BlockFix_CheckTool::Perform()
|
||||
Standard_Integer i = 1;
|
||||
for (; i <= aMapFacesEdges.Extent(); i++) {
|
||||
const TopTools_ListOfShape& ListEdges = aMapFacesEdges.FindFromIndex(i);
|
||||
if (ListEdges.Extent() > 1) break;
|
||||
if (ListEdges.Extent() > 1) {
|
||||
if (myAngTolerance < 0.) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check if edges have C1 continuity.
|
||||
if (!isC1(ListEdges)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i <= aMapFacesEdges.Extent()) {
|
||||
IsBlock = Standard_False;
|
||||
MayBeUE = Standard_True;
|
||||
break;
|
||||
}
|
||||
@ -265,3 +293,84 @@ void BlockFix_CheckTool::DumpCheckResult(Standard_OStream& S) const
|
||||
S<<" number of impossible blocks = "<<nbtmp<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : isC1
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean BlockFix_CheckTool::isC1
|
||||
(const TopTools_ListOfShape &theEdges) const
|
||||
{
|
||||
// Fill the map vertex - list of ancestor edges
|
||||
TopTools_IndexedDataMapOfShapeListOfShape aMapVE;
|
||||
TopTools_ListIteratorOfListOfShape anIter(theEdges);
|
||||
TopTools_MapOfShape aMapFence;
|
||||
Standard_Integer i;
|
||||
Standard_Integer aNbVtx;
|
||||
|
||||
for (; anIter.More(); anIter.Next()) {
|
||||
TopTools_IndexedMapOfShape aMapVtx;
|
||||
const TopoDS_Shape &anEdge = anIter.Value();
|
||||
|
||||
if (aMapFence.Add(anEdge)) {
|
||||
TopExp::MapShapes(anEdge, TopAbs_VERTEX, aMapVtx);
|
||||
aNbVtx = aMapVtx.Extent();
|
||||
|
||||
for (i = 1; i <= aNbVtx; ++i) {
|
||||
const TopoDS_Shape &aVtx = aMapVtx.FindKey(i);
|
||||
|
||||
if (!aMapVE.Contains(aVtx)) {
|
||||
aMapVE.Add(aVtx, TopTools_ListOfShape());
|
||||
}
|
||||
|
||||
aMapVE.ChangeFromKey(aVtx).Append(anEdge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check C1 continuity.
|
||||
Standard_Integer aNbEnds = 0;
|
||||
|
||||
for (i = 1, aNbVtx = aMapVE.Extent(); i <= aNbVtx; ++i) {
|
||||
const TopTools_ListOfShape &anEdges = aMapVE.FindFromIndex(i);
|
||||
Standard_Integer aNbEdges = anEdges.Extent();
|
||||
|
||||
if (aNbEdges == 1) {
|
||||
++aNbEnds;
|
||||
} else if (aNbEdges == 2) {
|
||||
TopoDS_Vertex aCommonVtx = TopoDS::Vertex(aMapVE.FindKey(i));
|
||||
TopoDS_Edge anEdge1 = TopoDS::Edge(anEdges.First());
|
||||
TopoDS_Edge anEdge2 = TopoDS::Edge(anEdges.Last());
|
||||
Standard_Real aParam1 = BRep_Tool::Parameter(aCommonVtx, anEdge1);
|
||||
Standard_Real aParam2 = BRep_Tool::Parameter(aCommonVtx, anEdge2);
|
||||
Standard_Real aPar[2];
|
||||
Handle(Geom_Curve) aCurve1 =
|
||||
BRep_Tool::Curve(anEdge1, aPar[0], aPar[1]);
|
||||
Handle(Geom_Curve) aCurve2 =
|
||||
BRep_Tool::Curve(anEdge2, aPar[0], aPar[1]);
|
||||
gp_Pnt aPnt;
|
||||
gp_Vec aVec1;
|
||||
gp_Vec aVec2;
|
||||
|
||||
aCurve1->D1(aParam1, aPnt, aVec1);
|
||||
aCurve2->D1(aParam2, aPnt, aVec2);
|
||||
|
||||
if (anEdge1.Orientation() != anEdge2.Orientation()) {
|
||||
// Orientations are different. One vector should be reversed.
|
||||
aVec1.Reverse();
|
||||
}
|
||||
|
||||
const Standard_Real anAngle = aVec1.Angle(aVec2);
|
||||
|
||||
if (anAngle > myAngTolerance) {
|
||||
// There is no C1 continuity.
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Non-manifold case.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (i > aNbVtx && aNbEnds == 2);
|
||||
}
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <Standard_OStream.hxx>
|
||||
|
||||
class TopoDS_Shape;
|
||||
class TopTools_ListOfShape;
|
||||
|
||||
#include <Standard.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
@ -38,14 +39,20 @@ class BlockFix_CheckTool {
|
||||
|
||||
public:
|
||||
Standard_EXPORT BlockFix_CheckTool();
|
||||
Standard_EXPORT void SetShape(const TopoDS_Shape& aShape) ;
|
||||
Standard_EXPORT void SetShape(const TopoDS_Shape& aShape);
|
||||
Standard_EXPORT void SetAngTolerance(const Standard_Real theTolerance);
|
||||
Standard_EXPORT void Perform() ;
|
||||
Standard_EXPORT Standard_Integer NbPossibleBlocks() const;
|
||||
Standard_EXPORT TopoDS_Shape PossibleBlock(const Standard_Integer num) const;
|
||||
Standard_EXPORT void DumpCheckResult(Standard_OStream& S) const;
|
||||
|
||||
private:
|
||||
TopoDS_Shape myShape;
|
||||
|
||||
Standard_Boolean isC1(const TopTools_ListOfShape &theEdges) const;
|
||||
|
||||
private:
|
||||
TopoDS_Shape myShape;
|
||||
Standard_Real myAngTolerance;
|
||||
Standard_Boolean myHasCheck;
|
||||
Standard_Integer myNbSolids;
|
||||
Standard_Integer myNbBlocks;
|
||||
|
@ -407,6 +407,10 @@ Please, select face, shell or solid and try again</translation>
|
||||
<source>GEOM_NONBLOCKS</source>
|
||||
<translation>NonBlocksGroup</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>GEOM_USE_C1_CRITERION</source>
|
||||
<translation>Use C1 criterion</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>GEOM_CHECK_INFOS</source>
|
||||
<translation>Object And Its Topological Information</translation>
|
||||
|
@ -88,6 +88,7 @@
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <GProp_GProps.hxx>
|
||||
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <Geom_Surface.hxx>
|
||||
#include <ShapeAnalysis_Surface.hxx>
|
||||
|
||||
@ -103,6 +104,147 @@
|
||||
#include <Standard_Failure.hxx>
|
||||
#include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
|
||||
|
||||
|
||||
/**
|
||||
* This function returns Standard_True if the face is quadrangular. It means
|
||||
* that it has only 1 wire with 4 edges. If there are more then 4 edges in
|
||||
* the wire and theToleranceC1 is not negative the new implementation is used.
|
||||
* According to it the face is quadrangular if it is quadrangular according to
|
||||
* an old implementation or if it has a single wire with more then 4 edges
|
||||
* that form exactly 4 bounds of C1 continuity with the given tolerance.
|
||||
*
|
||||
* \param theFace the face to be checked
|
||||
* \param theToleranceC1 if negative, it is not used; otherwise it is used
|
||||
* to check if two neighbor edges of face have C1 continuity.
|
||||
* \return Standard_True if the face is quadrangular; Standard_False otherwise.
|
||||
*/
|
||||
static Standard_Boolean IsQuadrangle(const TopoDS_Face &theFace,
|
||||
const Standard_Real theToleranceC1)
|
||||
{
|
||||
TopExp_Explorer aFExp (theFace, TopAbs_WIRE);
|
||||
|
||||
if (!aFExp.More()) {
|
||||
// no wire in the face
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
TopoDS_Shape aWire = aFExp.Current();
|
||||
|
||||
aFExp.Next();
|
||||
|
||||
if (aFExp.More()) {
|
||||
// multiple wires in the face
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// Check number of edges in the face
|
||||
Standard_Integer aNbEdges = 0;
|
||||
TopTools_MapOfShape aMapEdges;
|
||||
TopExp_Explorer aWExp(aWire, TopAbs_EDGE);
|
||||
|
||||
for (; aWExp.More(); aWExp.Next()) {
|
||||
if (aMapEdges.Add(aWExp.Current())) {
|
||||
aNbEdges++;
|
||||
|
||||
if (aNbEdges > 4) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aNbEdges < 4) {
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
if (aNbEdges > 4) {
|
||||
if (theToleranceC1 < 0.) {
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// Check if a wire has 4 bounds of C1 continuity.
|
||||
BRepTools_WireExplorer aWireExp(TopoDS::Wire(aWire), theFace);
|
||||
TopTools_ListOfShape anEdges;
|
||||
|
||||
for (aNbEdges = 0; aWireExp.More(); aWireExp.Next()) {
|
||||
const TopoDS_Edge &anEdge = aWireExp.Current();
|
||||
|
||||
// Skip degenerated edges.
|
||||
if (!BRep_Tool::Degenerated(anEdge)) {
|
||||
anEdges.Append(anEdge);
|
||||
++aNbEdges;
|
||||
}
|
||||
}
|
||||
|
||||
if (aNbEdges < 4) {
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// Compute number of sharp corners.
|
||||
anEdges.Append(anEdges.First()); // To make a loop.
|
||||
|
||||
TopTools_ListIteratorOfListOfShape anIter(anEdges);
|
||||
Standard_Real aPar[2];
|
||||
Standard_Integer aNbCorners = 0;
|
||||
TopoDS_Edge anEdge1 = TopoDS::Edge(anEdges.First());
|
||||
Handle(Geom_Curve) aCurve1 = BRep_Tool::Curve(anEdge1, aPar[0], aPar[1]);
|
||||
Handle(Geom_Curve) aCurve2;
|
||||
TopoDS_Edge anEdge2;
|
||||
TopoDS_Vertex aCommonVtx;
|
||||
gp_Pnt aPnt;
|
||||
gp_Vec aVec1;
|
||||
gp_Vec aVec2;
|
||||
Standard_Boolean isReversed1 = (anEdge1.Orientation() == TopAbs_REVERSED);
|
||||
Standard_Boolean isReversed2;
|
||||
|
||||
for (anIter.Next(); anIter.More(); anIter.Next()) {
|
||||
TopoDS_Edge anEdge2 = TopoDS::Edge(anIter.Value());
|
||||
|
||||
if (!TopExp::CommonVertex(anEdge1, anEdge2, aCommonVtx)) {
|
||||
// NEVERREACHED
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// Check the angle between tangent vectors of 2 curves at this point.
|
||||
Standard_Real aParam1 = BRep_Tool::Parameter(aCommonVtx, anEdge1);
|
||||
Standard_Real aParam2 = BRep_Tool::Parameter(aCommonVtx, anEdge2);
|
||||
|
||||
aCurve2 = BRep_Tool::Curve(anEdge2, aPar[0], aPar[1]);
|
||||
isReversed2 = (anEdge2.Orientation() == TopAbs_REVERSED);
|
||||
aCurve1->D1(aParam1, aPnt, aVec1);
|
||||
aCurve2->D1(aParam2, aPnt, aVec2);
|
||||
|
||||
if (isReversed1) {
|
||||
aVec1.Reverse();
|
||||
}
|
||||
|
||||
if (isReversed2) {
|
||||
aVec2.Reverse();
|
||||
}
|
||||
const Standard_Real anAngle = aVec1.Angle(aVec2);
|
||||
|
||||
if (anAngle > theToleranceC1) {
|
||||
++aNbCorners;
|
||||
|
||||
if (aNbCorners > 4) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Go to the next couple of edges.
|
||||
anEdge1 = anEdge2;
|
||||
aCurve1 = aCurve2;
|
||||
isReversed1 = isReversed2;
|
||||
}
|
||||
|
||||
// Check the total number of corners.
|
||||
if (aNbCorners != 4) {
|
||||
return Standard_False;
|
||||
}
|
||||
}
|
||||
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* constructor:
|
||||
@ -1647,7 +1789,8 @@ void GEOMImpl_IBlocksOperations::AddBlocksFrom (const TopoDS_Shape& theShape,
|
||||
TopTools_ListOfShape& BLO,
|
||||
TopTools_ListOfShape& NOT,
|
||||
TopTools_ListOfShape& EXT,
|
||||
TopTools_ListOfShape& NOQ)
|
||||
TopTools_ListOfShape& NOQ,
|
||||
const Standard_Real theToleranceC1)
|
||||
{
|
||||
TopAbs_ShapeEnum aType = theShape.ShapeType();
|
||||
switch (aType) {
|
||||
@ -1656,7 +1799,7 @@ void GEOMImpl_IBlocksOperations::AddBlocksFrom (const TopoDS_Shape& theShape,
|
||||
{
|
||||
TopoDS_Iterator It (theShape);
|
||||
for (; It.More(); It.Next()) {
|
||||
AddBlocksFrom(It.Value(), BLO, NOT, EXT, NOQ);
|
||||
AddBlocksFrom(It.Value(), BLO, NOT, EXT, NOQ, theToleranceC1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -1665,6 +1808,7 @@ void GEOMImpl_IBlocksOperations::AddBlocksFrom (const TopoDS_Shape& theShape,
|
||||
// Check, if there are seam or degenerated edges
|
||||
BlockFix_CheckTool aTool;
|
||||
aTool.SetShape(theShape);
|
||||
aTool.SetAngTolerance(theToleranceC1);
|
||||
aTool.Perform();
|
||||
if (aTool.NbPossibleBlocks() > 0) {
|
||||
EXT.Append(theShape);
|
||||
@ -1676,41 +1820,12 @@ void GEOMImpl_IBlocksOperations::AddBlocksFrom (const TopoDS_Shape& theShape,
|
||||
TopExp_Explorer expF (theShape, TopAbs_FACE);
|
||||
|
||||
for (; expF.More(); expF.Next()) {
|
||||
if (mapFaces.Add(expF.Current())) {
|
||||
TopoDS_Face aF = TopoDS::Face(expF.Current());
|
||||
|
||||
if (mapFaces.Add(aF)) {
|
||||
nbFaces++;
|
||||
//0021483//if (nbFaces > 6) break;
|
||||
|
||||
// get wire
|
||||
TopoDS_Shape aF = expF.Current();
|
||||
TopExp_Explorer wires (aF, TopAbs_WIRE);
|
||||
if (!wires.More()) {
|
||||
// no wire in the face
|
||||
hasNonQuadr = Standard_True;
|
||||
NOQ.Append(aF);//0021483
|
||||
//0021483//break;
|
||||
continue;
|
||||
}
|
||||
TopoDS_Shape aWire = wires.Current();
|
||||
wires.Next();
|
||||
if (wires.More()) {
|
||||
// multiple wires in the face
|
||||
hasNonQuadr = Standard_True;
|
||||
NOQ.Append(aF);//0021483
|
||||
//0021483//break;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check number of edges in the face
|
||||
Standard_Integer nbEdges = 0;
|
||||
TopTools_MapOfShape mapEdges;
|
||||
TopExp_Explorer expW (aWire, TopAbs_EDGE);
|
||||
for (; expW.More(); expW.Next()) {
|
||||
if (mapEdges.Add(expW.Current())) {
|
||||
nbEdges++;
|
||||
if (nbEdges > 4) break;
|
||||
}
|
||||
}
|
||||
if (nbEdges != 4) {
|
||||
if (!IsQuadrangle(aF, theToleranceC1)) {
|
||||
hasNonQuadr = Standard_True;
|
||||
NOQ.Append(aF);//0021483
|
||||
}
|
||||
@ -1732,34 +1847,10 @@ void GEOMImpl_IBlocksOperations::AddBlocksFrom (const TopoDS_Shape& theShape,
|
||||
TopTools_MapOfShape mapFaces;
|
||||
TopExp_Explorer expF (theShape, TopAbs_FACE);
|
||||
for (; expF.More(); expF.Next()) {
|
||||
if (mapFaces.Add(expF.Current())) {
|
||||
// get wire
|
||||
TopoDS_Shape aF = expF.Current();
|
||||
TopExp_Explorer wires (aF, TopAbs_WIRE);
|
||||
if (!wires.More()) {
|
||||
// no wire in the face
|
||||
NOQ.Append(aF);//0021483
|
||||
continue;
|
||||
}
|
||||
TopoDS_Shape aWire = wires.Current();
|
||||
wires.Next();
|
||||
if (wires.More()) {
|
||||
// multiple wires in the face
|
||||
NOQ.Append(aF);//0021483
|
||||
continue;
|
||||
}
|
||||
TopoDS_Face aF = TopoDS::Face(expF.Current());
|
||||
|
||||
// Check number of edges in the face
|
||||
Standard_Integer nbEdges = 0;
|
||||
TopTools_MapOfShape mapEdges;
|
||||
TopExp_Explorer expW (aWire, TopAbs_EDGE);
|
||||
for (; expW.More(); expW.Next()) {
|
||||
if (mapEdges.Add(expW.Current())) {
|
||||
nbEdges++;
|
||||
if (nbEdges > 4) break;
|
||||
}
|
||||
}
|
||||
if (nbEdges != 4) {
|
||||
if (mapFaces.Add(aF)) {
|
||||
if (!IsQuadrangle(aF, theToleranceC1)) {
|
||||
NOQ.Append(aF);//0021483
|
||||
}
|
||||
}
|
||||
@ -1771,99 +1862,6 @@ void GEOMImpl_IBlocksOperations::AddBlocksFrom (const TopoDS_Shape& theShape,
|
||||
}
|
||||
}
|
||||
|
||||
void AddBlocksFromOld (const TopoDS_Shape& theShape,
|
||||
TopTools_ListOfShape& BLO,
|
||||
TopTools_ListOfShape& NOT,
|
||||
TopTools_ListOfShape& DEG,
|
||||
TopTools_ListOfShape& SEA)
|
||||
{
|
||||
TopAbs_ShapeEnum aType = theShape.ShapeType();
|
||||
switch (aType) {
|
||||
case TopAbs_COMPOUND:
|
||||
case TopAbs_COMPSOLID:
|
||||
{
|
||||
TopoDS_Iterator It (theShape);
|
||||
for (; It.More(); It.Next()) {
|
||||
AddBlocksFromOld(It.Value(), BLO, NOT, DEG, SEA);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TopAbs_SOLID:
|
||||
{
|
||||
TopTools_MapOfShape mapFaces;
|
||||
TopExp_Explorer expF (theShape, TopAbs_FACE);
|
||||
Standard_Integer nbFaces = 0;
|
||||
Standard_Boolean hasNonQuadr = Standard_False;
|
||||
Standard_Boolean hasDegenerated = Standard_False;
|
||||
Standard_Boolean hasSeam = Standard_False;
|
||||
for (; expF.More(); expF.Next()) {
|
||||
if (mapFaces.Add(expF.Current())) {
|
||||
nbFaces++;
|
||||
if (nbFaces > 6) break;
|
||||
|
||||
// Check number of edges in the face
|
||||
Standard_Integer nbEdges = 0;
|
||||
TopTools_MapOfShape mapEdges;
|
||||
|
||||
// get wire
|
||||
TopoDS_Shape aF = expF.Current();
|
||||
TopExp_Explorer wires (aF, TopAbs_WIRE);
|
||||
if (!wires.More()) {
|
||||
// no wire in the face
|
||||
hasNonQuadr = Standard_True;
|
||||
break;
|
||||
}
|
||||
TopoDS_Shape aWire = wires.Current();
|
||||
wires.Next();
|
||||
if (wires.More()) {
|
||||
// multiple wires in the face
|
||||
hasNonQuadr = Standard_True;
|
||||
break;
|
||||
}
|
||||
|
||||
// iterate on wire
|
||||
BRepTools_WireExplorer aWE (TopoDS::Wire(aWire), TopoDS::Face(aF));
|
||||
for (; aWE.More(); aWE.Next(), nbEdges++) {
|
||||
if (BRep_Tool::Degenerated(aWE.Current())) {
|
||||
// degenerated edge found
|
||||
hasDegenerated = Standard_True;
|
||||
// break;
|
||||
}
|
||||
if (mapEdges.Contains(aWE.Current())) {
|
||||
// seam edge found
|
||||
hasSeam = Standard_True;
|
||||
// break;
|
||||
}
|
||||
mapEdges.Add(aWE.Current());
|
||||
}
|
||||
if (nbEdges != 4) {
|
||||
hasNonQuadr = Standard_True;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nbFaces == 6) {
|
||||
if (hasDegenerated || hasSeam) {
|
||||
if (hasDegenerated) {
|
||||
DEG.Append(theShape);
|
||||
}
|
||||
if (hasSeam) {
|
||||
SEA.Append(theShape);
|
||||
}
|
||||
} else if (hasNonQuadr) {
|
||||
NOT.Append(theShape);
|
||||
} else {
|
||||
BLO.Append(theShape);
|
||||
}
|
||||
} else {
|
||||
NOT.Append(theShape);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
NOT.Append(theShape);
|
||||
}
|
||||
}
|
||||
|
||||
#define REL_NOT_CONNECTED 0
|
||||
#define REL_OK 1
|
||||
#define REL_NOT_GLUED 2
|
||||
@ -2086,158 +2084,6 @@ Standard_Boolean HasAnyConnection (const Standard_Integer theBlockIndex,
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* CheckCompoundOfBlocksOld
|
||||
*/
|
||||
//=============================================================================
|
||||
Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocksOld
|
||||
(Handle(GEOM_Object) theCompound,
|
||||
std::list<BCError>& theErrors)
|
||||
{
|
||||
SetErrorCode(KO);
|
||||
|
||||
if (theCompound.IsNull()) return Standard_False;
|
||||
TopoDS_Shape aBlockOrComp = theCompound->GetValue();
|
||||
|
||||
Standard_Boolean isCompOfBlocks = Standard_True;
|
||||
|
||||
// Map sub-shapes and their indices
|
||||
TopTools_IndexedMapOfShape anIndices;
|
||||
TopExp::MapShapes(aBlockOrComp, anIndices);
|
||||
|
||||
// 1. Report non-blocks
|
||||
TopTools_ListOfShape NOT; // Not blocks
|
||||
TopTools_ListOfShape DEG; // Hexahedral solids, having degenerated edges
|
||||
TopTools_ListOfShape SEA; // Hexahedral solids, having seam edges
|
||||
TopTools_ListOfShape BLO; // All blocks from the given compound
|
||||
AddBlocksFromOld(aBlockOrComp, BLO, NOT, DEG, SEA);
|
||||
|
||||
if (NOT.Extent() > 0) {
|
||||
isCompOfBlocks = Standard_False;
|
||||
BCError anErr;
|
||||
anErr.error = NOT_BLOCK;
|
||||
TopTools_ListIteratorOfListOfShape it (NOT);
|
||||
for (; it.More(); it.Next()) {
|
||||
anErr.incriminated.push_back(anIndices.FindIndex(it.Value()));
|
||||
}
|
||||
theErrors.push_back(anErr);
|
||||
}
|
||||
|
||||
if (DEG.Extent() > 0 || SEA.Extent() > 0) {
|
||||
isCompOfBlocks = Standard_False;
|
||||
BCError anErr;
|
||||
anErr.error = EXTRA_EDGE;
|
||||
|
||||
TopTools_ListIteratorOfListOfShape itDEG (DEG);
|
||||
for (; itDEG.More(); itDEG.Next()) {
|
||||
anErr.incriminated.push_back(anIndices.FindIndex(itDEG.Value()));
|
||||
}
|
||||
|
||||
TopTools_ListIteratorOfListOfShape itSEA (SEA);
|
||||
for (; itSEA.More(); itSEA.Next()) {
|
||||
anErr.incriminated.push_back(anIndices.FindIndex(itSEA.Value()));
|
||||
}
|
||||
|
||||
theErrors.push_back(anErr);
|
||||
}
|
||||
|
||||
Standard_Integer nbBlocks = BLO.Extent();
|
||||
if (nbBlocks == 0) {
|
||||
isCompOfBlocks = Standard_False;
|
||||
SetErrorCode(OK);
|
||||
return isCompOfBlocks;
|
||||
}
|
||||
if (nbBlocks == 1) {
|
||||
SetErrorCode(OK);
|
||||
return isCompOfBlocks;
|
||||
}
|
||||
|
||||
// Convert list of blocks into array for easy and fast access
|
||||
Standard_Integer ibl = 1;
|
||||
TopTools_Array1OfShape aBlocks (1, nbBlocks);
|
||||
TopTools_ListIteratorOfListOfShape BLOit (BLO);
|
||||
for (; BLOit.More(); BLOit.Next(), ibl++) {
|
||||
aBlocks.SetValue(ibl, BLOit.Value());
|
||||
}
|
||||
|
||||
// 2. Find relations between all blocks,
|
||||
// report connection errors (NOT_GLUED and INVALID_CONNECTION)
|
||||
TColStd_Array2OfInteger aRelations (1, nbBlocks, 1, nbBlocks);
|
||||
aRelations.Init(REL_NOT_CONNECTED);
|
||||
|
||||
Standard_Integer row = 1;
|
||||
for (row = 1; row <= nbBlocks; row++) {
|
||||
TopoDS_Shape aBlock = aBlocks.Value(row);
|
||||
|
||||
Standard_Integer col = row + 1;
|
||||
for (; col <= nbBlocks; col++) {
|
||||
Standard_Integer aRel = BlocksRelation(aBlock, aBlocks.Value(col));
|
||||
if (aRel != REL_NOT_CONNECTED) {
|
||||
aRelations.SetValue(row, col, aRel);
|
||||
aRelations.SetValue(col, row, aRel);
|
||||
if (aRel == REL_NOT_GLUED) {
|
||||
// report connection error
|
||||
isCompOfBlocks = Standard_False;
|
||||
BCError anErr;
|
||||
anErr.error = NOT_GLUED;
|
||||
anErr.incriminated.push_back(anIndices.FindIndex(aBlocks.Value(row)));
|
||||
anErr.incriminated.push_back(anIndices.FindIndex(aBlocks.Value(col)));
|
||||
theErrors.push_back(anErr);
|
||||
} else if (aRel == REL_COLLISION_VV ||
|
||||
aRel == REL_COLLISION_FF ||
|
||||
aRel == REL_COLLISION_EE ||
|
||||
aRel == REL_UNKNOWN) {
|
||||
// report connection error
|
||||
isCompOfBlocks = Standard_False;
|
||||
BCError anErr;
|
||||
anErr.error = INVALID_CONNECTION;
|
||||
anErr.incriminated.push_back(anIndices.FindIndex(aBlocks.Value(row)));
|
||||
anErr.incriminated.push_back(anIndices.FindIndex(aBlocks.Value(col)));
|
||||
theErrors.push_back(anErr);
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Find largest set of connected (good connection or not glued) blocks
|
||||
TColStd_MapOfInteger aProcessedMap;
|
||||
TColStd_MapOfInteger aLargestSet;
|
||||
TColStd_MapOfInteger aCurrentSet;
|
||||
for (ibl = 1; ibl <= nbBlocks; ibl++) {
|
||||
if (!aProcessedMap.Contains(ibl)) {
|
||||
aCurrentSet.Clear();
|
||||
FindConnected(ibl, aRelations, aProcessedMap, aCurrentSet);
|
||||
if (aCurrentSet.Extent() > aLargestSet.Extent()) {
|
||||
aLargestSet = aCurrentSet;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Report all blocks, isolated from <aLargestSet>
|
||||
BCError anErr;
|
||||
anErr.error = NOT_CONNECTED;
|
||||
Standard_Boolean hasIsolated = Standard_False;
|
||||
for (ibl = 1; ibl <= nbBlocks; ibl++) {
|
||||
if (!aLargestSet.Contains(ibl)) {
|
||||
aProcessedMap.Clear();
|
||||
if (!HasAnyConnection(ibl, aLargestSet, aRelations, aProcessedMap)) {
|
||||
// report connection absence
|
||||
hasIsolated = Standard_True;
|
||||
anErr.incriminated.push_back(anIndices.FindIndex(aBlocks.Value(ibl)));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasIsolated) {
|
||||
isCompOfBlocks = Standard_False;
|
||||
theErrors.push_back(anErr);
|
||||
}
|
||||
|
||||
SetErrorCode(OK);
|
||||
return isCompOfBlocks;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* PrintBCErrors
|
||||
@ -2294,6 +2140,7 @@ TCollection_AsciiString GEOMImpl_IBlocksOperations::PrintBCErrors
|
||||
//=============================================================================
|
||||
Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocks
|
||||
(Handle(GEOM_Object) theCompound,
|
||||
const Standard_Real theToleranceC1,
|
||||
std::list<BCError>& theErrors)
|
||||
{
|
||||
SetErrorCode(KO);
|
||||
@ -2312,7 +2159,7 @@ Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocks
|
||||
TopTools_ListOfShape EXT; // Hexahedral solids, having degenerated and/or seam edges
|
||||
TopTools_ListOfShape BLO; // All blocks from the given compound
|
||||
TopTools_ListOfShape NOQ; // All non-quadrangular faces
|
||||
AddBlocksFrom(aBlockOrComp, BLO, NOT, EXT, NOQ);
|
||||
AddBlocksFrom(aBlockOrComp, BLO, NOT, EXT, NOQ, theToleranceC1);
|
||||
|
||||
// Report non-blocks
|
||||
if (NOT.Extent() > 0) {
|
||||
@ -2478,7 +2325,8 @@ Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocks
|
||||
*/
|
||||
//=============================================================================
|
||||
Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetNonBlocks
|
||||
(Handle(GEOM_Object) theShape,
|
||||
(Handle(GEOM_Object) theShape,
|
||||
const Standard_Real theToleranceC1,
|
||||
Handle(GEOM_Object)& theNonQuads)
|
||||
{
|
||||
SetErrorCode(KO);
|
||||
@ -2491,7 +2339,7 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetNonBlocks
|
||||
TopTools_ListOfShape NOT; // Not blocks
|
||||
TopTools_ListOfShape EXT; // Hexahedral solids, having degenerated and/or seam edges
|
||||
TopTools_ListOfShape NOQ; // All non-quadrangular faces
|
||||
AddBlocksFrom(aShape, BLO, NOT, EXT, NOQ);
|
||||
AddBlocksFrom(aShape, BLO, NOT, EXT, NOQ, theToleranceC1);
|
||||
|
||||
if (NOT.IsEmpty() && EXT.IsEmpty() && NOQ.IsEmpty()) {
|
||||
SetErrorCode("NOT_FOUND_ANY");
|
||||
|
@ -125,16 +125,15 @@ class GEOMImpl_IBlocksOperations : public GEOM_IOperations {
|
||||
std::list<int> incriminated;
|
||||
};
|
||||
|
||||
Standard_EXPORT Standard_Boolean CheckCompoundOfBlocksOld (Handle(GEOM_Object) theCompound,
|
||||
std::list<BCError>& theErrors);
|
||||
|
||||
Standard_EXPORT Standard_Boolean CheckCompoundOfBlocks (Handle(GEOM_Object) theCompound,
|
||||
const Standard_Real theToleranceC1,
|
||||
std::list<BCError>& theErrors);
|
||||
|
||||
Standard_EXPORT TCollection_AsciiString PrintBCErrors (Handle(GEOM_Object) theCompound,
|
||||
const std::list<BCError>& theErrors);
|
||||
|
||||
Standard_EXPORT Handle(GEOM_Object) GetNonBlocks (Handle(GEOM_Object) theShape,
|
||||
Standard_EXPORT Handle(GEOM_Object) GetNonBlocks (Handle(GEOM_Object) theShape,
|
||||
const Standard_Real theToleranceC1,
|
||||
Handle(GEOM_Object)& theNonQuads);
|
||||
|
||||
Standard_EXPORT Handle(GEOM_Object) RemoveExtraEdges (Handle(GEOM_Object) theShape,
|
||||
@ -148,7 +147,8 @@ class GEOMImpl_IBlocksOperations : public GEOM_IOperations {
|
||||
TopTools_ListOfShape& BLO,
|
||||
TopTools_ListOfShape& NOT,
|
||||
TopTools_ListOfShape& EXT,
|
||||
TopTools_ListOfShape& NOQ);
|
||||
TopTools_ListOfShape& NOQ,
|
||||
const Standard_Real theToleranceC1 = -1.);
|
||||
|
||||
// Extract blocks from blocks compounds
|
||||
Standard_EXPORT Handle(TColStd_HSequenceOfTransient) ExplodeCompoundOfBlocks
|
||||
|
8
src/GEOM_I/GEOM_IBlocksOperations_i.cc
Executable file → Normal file
8
src/GEOM_I/GEOM_IBlocksOperations_i.cc
Executable file → Normal file
@ -614,6 +614,7 @@ CORBA::Boolean GEOM_IBlocksOperations_i::IsCompoundOfBlocks
|
||||
//=============================================================================
|
||||
CORBA::Boolean GEOM_IBlocksOperations_i::CheckCompoundOfBlocks
|
||||
(GEOM::GEOM_Object_ptr theCompound,
|
||||
const CORBA::Double theToleranceC1,
|
||||
GEOM::GEOM_IBlocksOperations::BCErrors_out theErrors)
|
||||
{
|
||||
CORBA::Boolean isComp = false;
|
||||
@ -627,7 +628,8 @@ CORBA::Boolean GEOM_IBlocksOperations_i::CheckCompoundOfBlocks
|
||||
|
||||
//Check
|
||||
std::list<GEOMImpl_IBlocksOperations::BCError> errList;
|
||||
isComp = GetOperations()->CheckCompoundOfBlocks(aCompound, errList);
|
||||
isComp = GetOperations()->CheckCompoundOfBlocks
|
||||
(aCompound, theToleranceC1, errList);
|
||||
if (!GetOperations()->IsDone())
|
||||
return isComp;
|
||||
|
||||
@ -749,6 +751,7 @@ char* GEOM_IBlocksOperations_i::PrintBCErrors
|
||||
//=============================================================================
|
||||
GEOM::GEOM_Object_ptr GEOM_IBlocksOperations_i::GetNonBlocks
|
||||
(GEOM::GEOM_Object_ptr theShape,
|
||||
const CORBA::Double theToleranceC1,
|
||||
GEOM::GEOM_Object_out theNonQuads)
|
||||
{
|
||||
GEOM::GEOM_Object_var aGEOMObject;
|
||||
@ -765,7 +768,8 @@ GEOM::GEOM_Object_ptr GEOM_IBlocksOperations_i::GetNonBlocks
|
||||
|
||||
//Get the result
|
||||
Handle(GEOM_Object) aFaces;
|
||||
Handle(GEOM_Object) anObject = GetOperations()->GetNonBlocks(aShape, aFaces);
|
||||
Handle(GEOM_Object) anObject =
|
||||
GetOperations()->GetNonBlocks(aShape, theToleranceC1, aFaces);
|
||||
if (!GetOperations()->IsDone())
|
||||
return aGEOMObject._retn();
|
||||
|
||||
|
@ -116,12 +116,14 @@ class GEOM_I_EXPORT GEOM_IBlocksOperations_i :
|
||||
CORBA::Long& theNbBlocks);
|
||||
|
||||
CORBA::Boolean CheckCompoundOfBlocks (GEOM::GEOM_Object_ptr theCompound,
|
||||
const CORBA::Double theToleranceC1,
|
||||
GEOM::GEOM_IBlocksOperations::BCErrors_out theErrors);
|
||||
|
||||
char* PrintBCErrors (GEOM::GEOM_Object_ptr theCompound,
|
||||
const GEOM::GEOM_IBlocksOperations::BCErrors& theErrors);
|
||||
|
||||
GEOM::GEOM_Object_ptr GetNonBlocks (GEOM::GEOM_Object_ptr theShape,
|
||||
const CORBA::Double theToleranceC1,
|
||||
GEOM::GEOM_Object_out theNonQuads);
|
||||
|
||||
GEOM::GEOM_Object_ptr RemoveExtraEdges (GEOM::GEOM_Object_ptr theShape,
|
||||
|
@ -2713,7 +2713,7 @@ CORBA::Boolean GEOM_Superv_i::CheckCompoundOfBlocks
|
||||
beginService( " GEOM_Superv_i::CheckCompoundOfBlocks" );
|
||||
MESSAGE("GEOM_Superv_i::CheckCompoundOfBlocks");
|
||||
getBlocksOp();
|
||||
CORBA::Boolean aRes = myBlocksOp->CheckCompoundOfBlocks(theCompound, theErrors);
|
||||
CORBA::Boolean aRes = myBlocksOp->CheckCompoundOfBlocks(theCompound, -1., theErrors);
|
||||
endService( " GEOM_Superv_i::CheckCompoundOfBlocks" );
|
||||
return aRes;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@
|
||||
## # create and publish cylinder
|
||||
## cyl = geompy.MakeCylinderRH(100, 100, "cylinder")
|
||||
## # get non blocks from cylinder
|
||||
## g1, g2 = geompy.GetNonBlocks(cyl, "nonblock")
|
||||
## g1, g2 = geompy.GetNonBlocks(cyl, theName="nonblock")
|
||||
## @endcode
|
||||
##
|
||||
## Above example will publish both result compounds (first with non-hexa solids and
|
||||
@ -88,7 +88,7 @@
|
||||
## However, if second command is invoked as
|
||||
##
|
||||
## @code
|
||||
## g1, g2 = geompy.GetNonBlocks(cyl, ("nonhexa", "nonquad"))
|
||||
## g1, g2 = geompy.GetNonBlocks(cyl, theName=("nonhexa", "nonquad"))
|
||||
## @endcode
|
||||
##
|
||||
## ... the first compound will be published with "nonhexa" name, and second will be named "nonquad".
|
||||
@ -11425,36 +11425,62 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
|
||||
## Check, if the compound of blocks is given.
|
||||
# To be considered as a compound of blocks, the
|
||||
# given shape must satisfy the following conditions:
|
||||
# - Each element of the compound should be a Block (6 faces and 12 edges).
|
||||
# - Each element of the compound should be a Block (6 faces).
|
||||
# - Each face should be a quadrangle, i.e. it should have only 1 wire
|
||||
# with 4 edges. If <VAR>theIsUseC1</VAR> is set to True and
|
||||
# there are more than 4 edges in the only wire of a face,
|
||||
# this face is considered to be quadrangle if it has 4 bounds
|
||||
# (1 or more edge) of C1 continuity.
|
||||
# - A connection between two Blocks should be an entire quadrangle face or an entire edge.
|
||||
# - The compound should be connexe.
|
||||
# - The glue between two quadrangle faces should be applied.
|
||||
# @param theCompound The compound to check.
|
||||
# @param theIsUseC1 Flag to check if there are 4 bounds on a face
|
||||
# taking into account C1 continuity.
|
||||
# @param theAngTolerance the angular tolerance to check if two neighbor
|
||||
# edges are codirectional in the common vertex with this
|
||||
# tolerance. This parameter is used only if
|
||||
# <VAR>theIsUseC1</VAR> is set to True.
|
||||
# @return TRUE, if the given shape is a compound of blocks.
|
||||
# If theCompound is not valid, prints all discovered errors.
|
||||
#
|
||||
# @ref tui_measurement_tools_page "Example 1"
|
||||
# \n @ref swig_CheckCompoundOfBlocks "Example 2"
|
||||
@ManageTransactions("BlocksOp")
|
||||
def CheckCompoundOfBlocks(self,theCompound):
|
||||
def CheckCompoundOfBlocks(self,theCompound, theIsUseC1 = False,
|
||||
theAngTolerance = 1.e-12):
|
||||
"""
|
||||
Check, if the compound of blocks is given.
|
||||
To be considered as a compound of blocks, the
|
||||
given shape must satisfy the following conditions:
|
||||
- Each element of the compound should be a Block (6 faces and 12 edges).
|
||||
- Each element of the compound should be a Block (6 faces).
|
||||
- Each face should be a quadrangle, i.e. it should have only 1 wire
|
||||
with 4 edges. If theIsUseC1 is set to True and
|
||||
there are more than 4 edges in the only wire of a face,
|
||||
this face is considered to be quadrangle if it has 4 bounds
|
||||
(1 or more edge) of C1 continuity.
|
||||
- A connection between two Blocks should be an entire quadrangle face or an entire edge.
|
||||
- The compound should be connexe.
|
||||
- The glue between two quadrangle faces should be applied.
|
||||
|
||||
Parameters:
|
||||
theCompound The compound to check.
|
||||
theIsUseC1 Flag to check if there are 4 bounds on a face
|
||||
taking into account C1 continuity.
|
||||
theAngTolerance the angular tolerance to check if two neighbor
|
||||
edges are codirectional in the common vertex with this
|
||||
tolerance. This parameter is used only if
|
||||
theIsUseC1 is set to True.
|
||||
|
||||
Returns:
|
||||
TRUE, if the given shape is a compound of blocks.
|
||||
If theCompound is not valid, prints all discovered errors.
|
||||
"""
|
||||
# Example: see GEOM_Spanner.py
|
||||
(IsValid, BCErrors) = self.BlocksOp.CheckCompoundOfBlocks(theCompound)
|
||||
aTolerance = -1.0
|
||||
if theIsUseC1:
|
||||
aTolerance = theAngTolerance
|
||||
(IsValid, BCErrors) = self.BlocksOp.CheckCompoundOfBlocks(theCompound, aTolerance)
|
||||
RaiseIfFailed("CheckCompoundOfBlocks", self.BlocksOp)
|
||||
if IsValid == 0:
|
||||
Descr = self.BlocksOp.PrintBCErrors(theCompound, BCErrors)
|
||||
@ -11463,6 +11489,12 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
|
||||
|
||||
## Retrieve all non blocks solids and faces from \a theShape.
|
||||
# @param theShape The shape to explore.
|
||||
# @param theIsUseC1 Flag to check if there are 4 bounds on a face
|
||||
# taking into account C1 continuity.
|
||||
# @param theAngTolerance the angular tolerance to check if two neighbor
|
||||
# edges are codirectional in the common vertex with this
|
||||
# tolerance. This parameter is used only if
|
||||
# <VAR>theIsUseC1</VAR> is set to True.
|
||||
# @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.
|
||||
@ -11470,17 +11502,27 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
|
||||
# @return A tuple of two GEOM_Objects. The first object is a group of all
|
||||
# non block solids (= not 6 faces, or with 6 faces, but with the
|
||||
# presence of non-quadrangular faces). The second object is a
|
||||
# group of all non quadrangular faces.
|
||||
# group of all non quadrangular faces (= faces with more then
|
||||
# 1 wire or, if <VAR>theIsUseC1</VAR> is set to True, faces
|
||||
# with 1 wire with not 4 edges that do not form 4 bounds of
|
||||
# C1 continuity).
|
||||
#
|
||||
# @ref tui_measurement_tools_page "Example 1"
|
||||
# \n @ref swig_GetNonBlocks "Example 2"
|
||||
@ManageTransactions("BlocksOp")
|
||||
def GetNonBlocks (self, theShape, theName=None):
|
||||
def GetNonBlocks (self, theShape, theIsUseC1 = False,
|
||||
theAngTolerance = 1.e-12, theName=None):
|
||||
"""
|
||||
Retrieve all non blocks solids and faces from theShape.
|
||||
|
||||
Parameters:
|
||||
theShape The shape to explore.
|
||||
theIsUseC1 Flag to check if there are 4 bounds on a face
|
||||
taking into account C1 continuity.
|
||||
theAngTolerance the angular tolerance to check if two neighbor
|
||||
edges are codirectional in the common vertex with this
|
||||
tolerance. This parameter is used only if
|
||||
theIsUseC1 is set to True.
|
||||
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.
|
||||
@ -11489,13 +11531,19 @@ class geomBuilder(object, GEOM._objref_GEOM_Gen):
|
||||
A tuple of two GEOM_Objects. The first object is a group of all
|
||||
non block solids (= not 6 faces, or with 6 faces, but with the
|
||||
presence of non-quadrangular faces). The second object is a
|
||||
group of all non quadrangular faces.
|
||||
group of all non quadrangular faces (= faces with more then
|
||||
1 wire or, if <VAR>theIsUseC1</VAR> is set to True, faces
|
||||
with 1 wire with not 4 edges that do not form 4 bounds of
|
||||
C1 continuity).
|
||||
|
||||
Usage:
|
||||
(res_sols, res_faces) = geompy.GetNonBlocks(myShape1)
|
||||
"""
|
||||
# Example: see GEOM_Spanner.py
|
||||
aTuple = self.BlocksOp.GetNonBlocks(theShape)
|
||||
aTolerance = -1.0
|
||||
if theIsUseC1:
|
||||
aTolerance = theAngTolerance
|
||||
aTuple = self.BlocksOp.GetNonBlocks(theShape, aTolerance)
|
||||
RaiseIfFailed("GetNonBlocks", self.BlocksOp)
|
||||
self._autoPublish(aTuple, theName, ("groupNonHexas", "groupNonQuads"))
|
||||
return aTuple
|
||||
|
@ -26,7 +26,6 @@
|
||||
//
|
||||
#include "MeasureGUI.h"
|
||||
#include "MeasureGUI_CheckCompoundOfBlocksDlg.h"
|
||||
#include "MeasureGUI_Widgets.h"
|
||||
|
||||
#include <SUIT_Session.h>
|
||||
#include <SUIT_ResourceMgr.h>
|
||||
@ -43,6 +42,8 @@
|
||||
#include <GEOMBase.h>
|
||||
#include <GEOMImpl_Types.hxx>
|
||||
|
||||
#include <QListWidget>
|
||||
|
||||
#define TEXTEDIT_FONT_FAMILY "Courier"
|
||||
#define TEXTEDIT_FONT_SIZE 11
|
||||
|
||||
@ -54,7 +55,15 @@
|
||||
// true to construct a modal dialog.
|
||||
//=================================================================================
|
||||
MeasureGUI_CheckCompoundOfBlocksDlg::MeasureGUI_CheckCompoundOfBlocksDlg( GeometryGUI* GUI, QWidget* parent )
|
||||
: GEOMBase_Skeleton( GUI, parent, false )
|
||||
: GEOMBase_Skeleton(GUI, parent, false),
|
||||
myObjectName (0),
|
||||
mySelButton (0),
|
||||
myUseC1Check (0),
|
||||
myTolLbl (0),
|
||||
mySpinTol (0),
|
||||
myTextView (0),
|
||||
myListBox1 (0),
|
||||
myListBox2 (0)
|
||||
{
|
||||
SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
|
||||
QPixmap image0( aResMgr->loadPixmap( "GEOM", tr( "ICON_DLG_CHECK_COMPOUND_OF_BLOCKS" ) ) );
|
||||
@ -70,29 +79,55 @@ MeasureGUI_CheckCompoundOfBlocksDlg::MeasureGUI_CheckCompoundOfBlocksDlg( Geomet
|
||||
mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
|
||||
mainFrame()->RadioButton3->close();
|
||||
|
||||
myGrp = new MeasureGUI_1Sel1TextView2ListBox( centralWidget() );
|
||||
myGrp->GroupBox1->setTitle( tr( "GEOM_CHECK_INFOS" ) );
|
||||
myGrp->TextLabel1->setText( tr( "GEOM_OBJECT" ) );
|
||||
QGroupBox *aGrpParams =
|
||||
new QGroupBox(tr("GEOM_CHECK_INFOS"), centralWidget());
|
||||
QGridLayout *aParamsLayout = new QGridLayout(aGrpParams);
|
||||
QLabel *anObjLbl = new QLabel(tr("GEOM_OBJECT"), aGrpParams);
|
||||
QLabel *anErrorsLbl =
|
||||
new QLabel(tr("GEOM_CHECK_BLOCKS_COMPOUND_ERRORS"), aGrpParams);
|
||||
QLabel *aNonBlocksLbl =
|
||||
new QLabel(tr("GEOM_CHECK_BLOCKS_COMPOUND_SUBSHAPES"), aGrpParams);
|
||||
|
||||
myGrp->TextView1->setReadOnly( true );
|
||||
QFont aFont( TEXTEDIT_FONT_FAMILY, TEXTEDIT_FONT_SIZE );
|
||||
aFont.setStyleHint( QFont::TypeWriter, QFont::PreferAntialias );
|
||||
myGrp->TextView1->setFont( aFont );
|
||||
myObjectName = new QLineEdit(aGrpParams);
|
||||
mySelButton = new QPushButton(aGrpParams);
|
||||
myUseC1Check = new QCheckBox(tr("GEOM_USE_C1_CRITERION"), aGrpParams);
|
||||
myTolLbl = new QLabel(tr("GEOM_ANGULAR_TOLERANCE"), aGrpParams);
|
||||
mySpinTol = new SalomeApp_DoubleSpinBox(aGrpParams);
|
||||
myTextView = new QTextBrowser(aGrpParams);
|
||||
myListBox1 = new QListWidget(aGrpParams);
|
||||
myListBox2 = new QListWidget(aGrpParams);
|
||||
|
||||
myGrp->PushButton1->setIcon( image1 );
|
||||
myGrp->LineEdit1->setReadOnly( true );
|
||||
myObjectName->setReadOnly(true);
|
||||
mySelButton->setIcon(image1);
|
||||
mySelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
myUseC1Check->setText(tr("GEOM_USE_C1_CRITERION"));
|
||||
myUseC1Check->setChecked(true);
|
||||
myTextView->setReadOnly(true);
|
||||
myListBox2->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
myGrp->TextLabel2->setText( tr( "GEOM_CHECK_BLOCKS_COMPOUND_ERRORS" ) );
|
||||
myGrp->TextLabel3->setText( tr( "GEOM_CHECK_BLOCKS_COMPOUND_SUBSHAPES" ) );
|
||||
// Set text view font.
|
||||
QFont aFont(TEXTEDIT_FONT_FAMILY, TEXTEDIT_FONT_SIZE);
|
||||
|
||||
myGrp->ListBox2->setSelectionMode( QAbstractItemView::ExtendedSelection );
|
||||
aFont.setStyleHint(QFont::TypeWriter, QFont::PreferAntialias);
|
||||
myTextView->setFont(aFont);
|
||||
|
||||
aParamsLayout->setMargin(9);
|
||||
aParamsLayout->setSpacing(6);
|
||||
aParamsLayout->addWidget(anObjLbl, 0, 0);
|
||||
aParamsLayout->addWidget(mySelButton, 0, 1);
|
||||
aParamsLayout->addWidget(myObjectName, 0, 2);
|
||||
aParamsLayout->addWidget(myUseC1Check, 1, 0, 1, 3);
|
||||
aParamsLayout->addWidget(myTolLbl, 2, 0);
|
||||
aParamsLayout->addWidget(mySpinTol, 2, 1, 1, 2);
|
||||
aParamsLayout->addWidget(myTextView, 3, 0, 1, 3);
|
||||
aParamsLayout->addWidget(anErrorsLbl, 4, 0);
|
||||
aParamsLayout->addWidget(myListBox1, 5, 0, 1, 2);
|
||||
aParamsLayout->addWidget(aNonBlocksLbl, 4, 2);
|
||||
aParamsLayout->addWidget(myListBox2, 5, 2);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout( centralWidget() );
|
||||
layout->setMargin( 0 ); layout->setSpacing( 6 );
|
||||
layout->addWidget( myGrp );
|
||||
|
||||
connect( myGrp->ListBox1, SIGNAL( itemSelectionChanged() ), SLOT( onErrorsListSelectionChanged() ) );
|
||||
connect( myGrp->ListBox2, SIGNAL( itemSelectionChanged() ), SLOT( onSubShapesListSelectionChanged() ) );
|
||||
layout->addWidget( aGrpParams );
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
@ -116,14 +151,24 @@ MeasureGUI_CheckCompoundOfBlocksDlg::~MeasureGUI_CheckCompoundOfBlocksDlg()
|
||||
//=================================================================================
|
||||
void MeasureGUI_CheckCompoundOfBlocksDlg::Init()
|
||||
{
|
||||
myEditCurrentArgument = myGrp->LineEdit1;
|
||||
/* init variables */
|
||||
double SpecificStep = 0.0001;
|
||||
double aDefaultTol = Precision::Angular();
|
||||
|
||||
initSpinBox(mySpinTol, aDefaultTol, MAX_NUMBER, SpecificStep, "ang_tol_precision");
|
||||
mySpinTol->setValue(aDefaultTol);
|
||||
myEditCurrentArgument = myObjectName;
|
||||
|
||||
// signals and slots connections
|
||||
connect( buttonOk(), SIGNAL( clicked() ), this, SLOT( ClickOnOk() ) );
|
||||
connect( buttonApply(), SIGNAL( clicked() ), this, SLOT( ClickOnApply() ) );
|
||||
|
||||
connect( myGrp->LineEdit1, SIGNAL( returnPressed() ), this, SLOT( LineEditReturnPressed() ) );
|
||||
connect( myGrp->PushButton1, SIGNAL( clicked() ), this, SLOT( SetEditCurrentArgument() ) );
|
||||
connect(myObjectName, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
|
||||
connect(mySelButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
|
||||
connect(myListBox1, SIGNAL(itemSelectionChanged()), this, SLOT(onErrorsListSelectionChanged()));
|
||||
connect(myListBox2, SIGNAL(itemSelectionChanged()), this, SLOT(onSubShapesListSelectionChanged()));
|
||||
connect(myUseC1Check, SIGNAL(clicked()), this, SLOT(SetUseC1Tolerance()));
|
||||
connect(mySpinTol, SIGNAL(valueChanged(double)), this, SLOT(processObject()));
|
||||
|
||||
connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),
|
||||
this, SLOT( SelectionIntoArgument() ) );
|
||||
@ -172,7 +217,7 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::SelectionIntoArgument()
|
||||
aSelMgr->selectedObjects(aSelList);
|
||||
|
||||
if (aSelList.Extent() != 1) {
|
||||
myGrp->LineEdit1->setText( "" );
|
||||
myObjectName->setText( "" );
|
||||
processObject();
|
||||
return;
|
||||
}
|
||||
@ -181,13 +226,13 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::SelectionIntoArgument()
|
||||
GEOMBase::ConvertIOinGEOMObject( aSelList.First() );
|
||||
|
||||
if ( aSelectedObject->_is_nil() ) {
|
||||
myGrp->LineEdit1->setText( "" );
|
||||
myObjectName->setText( "" );
|
||||
processObject();
|
||||
return;
|
||||
}
|
||||
|
||||
myObj = aSelectedObject;
|
||||
myGrp->LineEdit1->setText( GEOMBase::GetName( myObj ) );
|
||||
myObjectName->setText( GEOMBase::GetName( myObj ) );
|
||||
processObject();
|
||||
DISPLAY_PREVIEW_MACRO;
|
||||
}
|
||||
@ -198,11 +243,22 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::SelectionIntoArgument()
|
||||
//=================================================================================
|
||||
void MeasureGUI_CheckCompoundOfBlocksDlg::SetEditCurrentArgument()
|
||||
{
|
||||
myGrp->LineEdit1->setFocus();
|
||||
myEditCurrentArgument = myGrp->LineEdit1;
|
||||
myObjectName->setFocus();
|
||||
myEditCurrentArgument = myObjectName;
|
||||
SelectionIntoArgument();
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
// function : SetUseC1Tolerance()
|
||||
// purpose :
|
||||
//=================================================================================
|
||||
void MeasureGUI_CheckCompoundOfBlocksDlg::SetUseC1Tolerance()
|
||||
{
|
||||
myTolLbl->setEnabled(myUseC1Check->isChecked());
|
||||
mySpinTol->setEnabled(myUseC1Check->isChecked());
|
||||
processObject();
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
// function : LineEditReturnPressed()
|
||||
// purpose :
|
||||
@ -210,8 +266,8 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::SetEditCurrentArgument()
|
||||
void MeasureGUI_CheckCompoundOfBlocksDlg::LineEditReturnPressed()
|
||||
{
|
||||
QLineEdit* send = (QLineEdit*)sender();
|
||||
if ( send == myGrp->LineEdit1 ) {
|
||||
myEditCurrentArgument = myGrp->LineEdit1;
|
||||
if ( send == myObjectName ) {
|
||||
myEditCurrentArgument = myObjectName;
|
||||
GEOMBase_Skeleton::LineEditReturnPressed();
|
||||
}
|
||||
}
|
||||
@ -245,7 +301,13 @@ bool MeasureGUI_CheckCompoundOfBlocksDlg::getBCErrors( bool& theIsCompoundOfBloc
|
||||
GEOM::GEOM_IBlocksOperations_var anOper = GEOM::GEOM_IBlocksOperations::_narrow( getOperation() );
|
||||
try {
|
||||
GEOM::GEOM_IBlocksOperations::BCErrors_var aErrs;
|
||||
theIsCompoundOfBlocks = anOper->CheckCompoundOfBlocks( myObj, aErrs );
|
||||
double aC1Tol = -1.;
|
||||
|
||||
if (myUseC1Check->isChecked()) {
|
||||
aC1Tol = mySpinTol->value();
|
||||
}
|
||||
|
||||
theIsCompoundOfBlocks = anOper->CheckCompoundOfBlocks( myObj, aC1Tol, aErrs );
|
||||
if (anOper->IsDone() && aErrs->length() > 0)
|
||||
//if (anOper->IsDone() && !aErrs._is_nil())
|
||||
theErrors = aErrs;
|
||||
@ -270,9 +332,9 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::processObject()
|
||||
GEOM::GEOM_IBlocksOperations::BCErrors aErrs;
|
||||
if ( !getBCErrors( isCompoundOfBlocks, aErrs ) ) {
|
||||
aMsg += tr( "GEOM_CHECK_BLOCKS_COMPOUND_FAILED" );
|
||||
myGrp->TextView1->setText( aMsg );
|
||||
myGrp->ListBox1->clear();
|
||||
myGrp->ListBox2->clear();
|
||||
myTextView->setText( aMsg );
|
||||
myListBox1->clear();
|
||||
myListBox2->clear();
|
||||
erasePreview();
|
||||
return;
|
||||
}
|
||||
@ -287,7 +349,7 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::processObject()
|
||||
buttonOk()->setEnabled( true );
|
||||
buttonApply()->setEnabled( true );
|
||||
}
|
||||
myGrp->TextView1->setText( aMsg );
|
||||
myTextView->setText( aMsg );
|
||||
|
||||
QStringList aErrList;
|
||||
QString aErrStr( "" );
|
||||
@ -321,9 +383,9 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::processObject()
|
||||
aErrList.append( aErrStr );
|
||||
}
|
||||
|
||||
myGrp->ListBox1->clear();
|
||||
myGrp->ListBox2->clear();
|
||||
myGrp->ListBox1->addItems( aErrList );
|
||||
myListBox1->clear();
|
||||
myListBox2->clear();
|
||||
myListBox1->addItems( aErrList );
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
@ -342,19 +404,19 @@ GEOM::GEOM_IOperations_ptr MeasureGUI_CheckCompoundOfBlocksDlg::createOperation(
|
||||
void MeasureGUI_CheckCompoundOfBlocksDlg::onErrorsListSelectionChanged()
|
||||
{
|
||||
erasePreview();
|
||||
int aCurItem = myGrp->ListBox1->currentRow();
|
||||
int aCurItem = myListBox1->currentRow();
|
||||
if ( aCurItem < 0 )
|
||||
return;
|
||||
bool isCompoundOfBlocks;
|
||||
GEOM::GEOM_IBlocksOperations::BCErrors aErrs;
|
||||
if ( !getBCErrors( isCompoundOfBlocks, aErrs ) ) {
|
||||
myGrp->TextView1->setText( "" );
|
||||
myGrp->ListBox1->clear();
|
||||
myGrp->ListBox2->clear();
|
||||
myTextView->setText( "" );
|
||||
myListBox1->clear();
|
||||
myListBox2->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
myGrp->ListBox2->clear();
|
||||
myListBox2->clear();
|
||||
|
||||
if (aCurItem < aErrs.length()) {
|
||||
GEOM::GEOM_IBlocksOperations::BCError aErr = aErrs[aCurItem];
|
||||
@ -371,7 +433,7 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::onErrorsListSelectionChanged()
|
||||
aSubShapeList.append( QString( "%1_%2" ).arg( aType ).arg( aObjLst[i] ) );
|
||||
}
|
||||
}
|
||||
myGrp->ListBox2->addItems( aSubShapeList );
|
||||
myListBox2->addItems( aSubShapeList );
|
||||
}
|
||||
}
|
||||
|
||||
@ -382,12 +444,12 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::onErrorsListSelectionChanged()
|
||||
void MeasureGUI_CheckCompoundOfBlocksDlg::onSubShapesListSelectionChanged()
|
||||
{
|
||||
erasePreview();
|
||||
int aErrCurItem = myGrp->ListBox1->currentRow();
|
||||
int aErrCurItem = myListBox1->currentRow();
|
||||
if ( aErrCurItem < 0 )
|
||||
return;
|
||||
QList<int> aIds;
|
||||
for ( int i = 0, n = myGrp->ListBox2->count(); i < n; i++ ) {
|
||||
if ( myGrp->ListBox2->item( i )->isSelected() )
|
||||
for ( int i = 0, n = myListBox2->count(); i < n; i++ ) {
|
||||
if ( myListBox2->item( i )->isSelected() )
|
||||
aIds.append( i );
|
||||
}
|
||||
if ( aIds.count() < 1 )
|
||||
@ -395,9 +457,9 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::onSubShapesListSelectionChanged()
|
||||
bool isCompoundOfBlocks;
|
||||
GEOM::GEOM_IBlocksOperations::BCErrors aErrs;
|
||||
if ( !getBCErrors( isCompoundOfBlocks, aErrs ) ) {
|
||||
myGrp->TextView1->setText( "" );
|
||||
myGrp->ListBox1->clear();
|
||||
myGrp->ListBox2->clear();
|
||||
myTextView->setText( "" );
|
||||
myListBox1->clear();
|
||||
myListBox2->clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -433,6 +495,15 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::onSubShapesListSelectionChanged()
|
||||
}
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
// function : onDisplayPreview
|
||||
// purpose :
|
||||
//=================================================================================
|
||||
void MeasureGUI_CheckCompoundOfBlocksDlg::onDisplayPreview()
|
||||
{
|
||||
DISPLAY_PREVIEW_MACRO;
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
// function : activateSelection
|
||||
// purpose : activate selection of faces, shells, and solids
|
||||
@ -459,9 +530,9 @@ void MeasureGUI_CheckCompoundOfBlocksDlg::enterEvent( QEvent* )
|
||||
// function : isValid
|
||||
// purpose :
|
||||
//=================================================================================
|
||||
bool MeasureGUI_CheckCompoundOfBlocksDlg::isValid( QString& )
|
||||
bool MeasureGUI_CheckCompoundOfBlocksDlg::isValid( QString &msg)
|
||||
{
|
||||
return !myObj->_is_nil();
|
||||
return !myObj->_is_nil() && mySpinTol->isValid(msg, !IsPreview());
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
|
@ -29,7 +29,13 @@
|
||||
|
||||
#include <GEOMBase_Skeleton.h>
|
||||
|
||||
class MeasureGUI_1Sel1TextView2ListBox;
|
||||
class QCheckBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QListWidget;
|
||||
class QPushButton;
|
||||
class QTextBrowser;
|
||||
class SalomeApp_DoubleSpinBox;
|
||||
|
||||
//=================================================================================
|
||||
// class : MeasureGUI_CheckCompoundOfBlocksDlg
|
||||
@ -47,7 +53,7 @@ public:
|
||||
protected:
|
||||
// redefined from GEOMBase_Helper and GEOMBase_Skeleton
|
||||
virtual GEOM::GEOM_IOperations_ptr createOperation();
|
||||
virtual bool isValid( QString& );
|
||||
virtual bool isValid( QString &msg );
|
||||
virtual bool execute( ObjectList& );
|
||||
virtual void processObject();
|
||||
|
||||
@ -61,6 +67,8 @@ private slots:
|
||||
|
||||
void onErrorsListSelectionChanged();
|
||||
void onSubShapesListSelectionChanged();
|
||||
void SetUseC1Tolerance();
|
||||
void onDisplayPreview();
|
||||
|
||||
private:
|
||||
void Init();
|
||||
@ -71,7 +79,14 @@ private:
|
||||
|
||||
private:
|
||||
GEOM::GEOM_Object_var myObj;
|
||||
MeasureGUI_1Sel1TextView2ListBox* myGrp;
|
||||
QLineEdit *myObjectName;
|
||||
QPushButton *mySelButton;
|
||||
QCheckBox *myUseC1Check;
|
||||
QLabel *myTolLbl;
|
||||
SalomeApp_DoubleSpinBox *mySpinTol;
|
||||
QTextBrowser *myTextView;
|
||||
QListWidget *myListBox1;
|
||||
QListWidget *myListBox2;
|
||||
};
|
||||
|
||||
#endif // MEASUREGUI_CHECKCOMPOUNDOFBLOCKSDLG_H
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
#include "MeasureGUI_GetNonBlocksDlg.h"
|
||||
|
||||
#include <DlgRef.h>
|
||||
#include <GEOMBase.h>
|
||||
|
||||
#include <GeometryGUI.h>
|
||||
@ -33,9 +32,18 @@
|
||||
#include <SUIT_Session.h>
|
||||
#include <SUIT_ResourceMgr.h>
|
||||
#include <SalomeApp_Application.h>
|
||||
#include <SalomeApp_DoubleSpinBox.h>
|
||||
#include <LightApp_SelectionMgr.h>
|
||||
#include <SalomeApp_Tools.h>
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
//=================================================================================
|
||||
// class : MeasureGUI_GetNonBlocksDlg()
|
||||
// purpose : Constructs a MeasureGUI_GetNonBlocksDlg which is a child of 'parent',
|
||||
@ -44,7 +52,12 @@
|
||||
// true to construct a modal dialog.
|
||||
//=================================================================================
|
||||
MeasureGUI_GetNonBlocksDlg::MeasureGUI_GetNonBlocksDlg (GeometryGUI* theGeometryGUI, QWidget* parent)
|
||||
: GEOMBase_Skeleton(theGeometryGUI, parent, false)
|
||||
: GEOMBase_Skeleton(theGeometryGUI, parent, false),
|
||||
myObjectName (0),
|
||||
mySelButton (0),
|
||||
myUseC1Check (0),
|
||||
myTolLbl (0),
|
||||
mySpinTol (0)
|
||||
{
|
||||
QPixmap image0 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_GETNONBLOCKS")));
|
||||
QPixmap image1 (SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
|
||||
@ -58,16 +71,36 @@ MeasureGUI_GetNonBlocksDlg::MeasureGUI_GetNonBlocksDlg (GeometryGUI* theGeometry
|
||||
mainFrame()->RadioButton2->close();
|
||||
mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
|
||||
mainFrame()->RadioButton3->close();
|
||||
|
||||
QGroupBox *aGrpParams =
|
||||
new QGroupBox(tr("GEOM_GETNONBLOCKS"), centralWidget());
|
||||
QGridLayout *aParamsLayout = new QGridLayout(aGrpParams);
|
||||
QLabel *anObjLbl = new QLabel(tr("GEOM_OBJECT"), aGrpParams);
|
||||
|
||||
myGrp = new DlgRef_1Sel (centralWidget());
|
||||
myGrp->GroupBox1->setTitle(tr("GEOM_GETNONBLOCKS"));
|
||||
myGrp->TextLabel1->setText(tr("GEOM_OBJECT"));
|
||||
myGrp->PushButton1->setIcon(image1);
|
||||
myGrp->LineEdit1->setReadOnly(true);
|
||||
myObjectName = new QLineEdit(aGrpParams);
|
||||
mySelButton = new QPushButton(aGrpParams);
|
||||
myUseC1Check = new QCheckBox(tr("GEOM_USE_C1_CRITERION"), aGrpParams);
|
||||
myTolLbl = new QLabel(tr("GEOM_ANGULAR_TOLERANCE"), aGrpParams);
|
||||
mySpinTol = new SalomeApp_DoubleSpinBox(aGrpParams);
|
||||
|
||||
myObjectName->setReadOnly(true);
|
||||
mySelButton->setIcon(image1);
|
||||
mySelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
myUseC1Check->setText(tr("GEOM_USE_C1_CRITERION"));
|
||||
myUseC1Check->setChecked(true);
|
||||
|
||||
aParamsLayout->setMargin(9);
|
||||
aParamsLayout->setSpacing(6);
|
||||
aParamsLayout->addWidget(anObjLbl, 0, 0);
|
||||
aParamsLayout->addWidget(mySelButton, 0, 1);
|
||||
aParamsLayout->addWidget(myObjectName, 0, 2);
|
||||
aParamsLayout->addWidget(myUseC1Check, 1, 0, 1, 3);
|
||||
aParamsLayout->addWidget(myTolLbl, 2, 0);
|
||||
aParamsLayout->addWidget(mySpinTol, 2, 1, 1, 2);
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout(centralWidget());
|
||||
layout->setMargin(0); layout->setSpacing(6);
|
||||
layout->addWidget(myGrp);
|
||||
layout->addWidget(aGrpParams);
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
@ -94,14 +127,20 @@ void MeasureGUI_GetNonBlocksDlg::Init()
|
||||
showOnlyPreviewControl();
|
||||
|
||||
/* init variables */
|
||||
myEditCurrentArgument = myGrp->LineEdit1;
|
||||
double SpecificStep = 0.0001;
|
||||
double aDefaultTol = Precision::Angular();
|
||||
|
||||
initSpinBox(mySpinTol, aDefaultTol, MAX_NUMBER, SpecificStep, "ang_tol_precision");
|
||||
mySpinTol->setValue(aDefaultTol);
|
||||
myEditCurrentArgument = myObjectName;
|
||||
|
||||
/* signals and slots connections */
|
||||
connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
|
||||
connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
|
||||
|
||||
connect(myGrp->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
|
||||
connect(myGrp->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
|
||||
connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
|
||||
connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
|
||||
connect(myUseC1Check, SIGNAL(clicked()), this, SLOT(SetUseC1Tolerance()));
|
||||
connect(mySpinTol, SIGNAL(valueChanged(double)), this, SLOT(processPreview()));
|
||||
connect(myObjectName, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
|
||||
connect(mySelButton, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
|
||||
|
||||
connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
|
||||
SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
|
||||
@ -171,11 +210,22 @@ void MeasureGUI_GetNonBlocksDlg::SelectionIntoArgument()
|
||||
//=================================================================================
|
||||
void MeasureGUI_GetNonBlocksDlg::SetEditCurrentArgument()
|
||||
{
|
||||
myGrp->LineEdit1->setFocus();
|
||||
myEditCurrentArgument = myGrp->LineEdit1;
|
||||
myObjectName->setFocus();
|
||||
myEditCurrentArgument = myObjectName;
|
||||
SelectionIntoArgument();
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
// function : SetUseC1Tolerance()
|
||||
// purpose :
|
||||
//=================================================================================
|
||||
void MeasureGUI_GetNonBlocksDlg::SetUseC1Tolerance()
|
||||
{
|
||||
myTolLbl->setEnabled(myUseC1Check->isChecked());
|
||||
mySpinTol->setEnabled(myUseC1Check->isChecked());
|
||||
processPreview();
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
// function : LineEditReturnPressed()
|
||||
// purpose :
|
||||
@ -183,8 +233,8 @@ void MeasureGUI_GetNonBlocksDlg::SetEditCurrentArgument()
|
||||
void MeasureGUI_GetNonBlocksDlg::LineEditReturnPressed()
|
||||
{
|
||||
QLineEdit* send = (QLineEdit*)sender();
|
||||
if (send == myGrp->LineEdit1) {
|
||||
myEditCurrentArgument = myGrp->LineEdit1;
|
||||
if (send == myObjectName) {
|
||||
myEditCurrentArgument = myObjectName;
|
||||
GEOMBase_Skeleton::LineEditReturnPressed();
|
||||
}
|
||||
}
|
||||
@ -211,10 +261,11 @@ void MeasureGUI_GetNonBlocksDlg::ActivateThisDialog()
|
||||
void MeasureGUI_GetNonBlocksDlg::processObject()
|
||||
{
|
||||
if (myObj->_is_nil()) {
|
||||
myObjectName->setText("");
|
||||
erasePreview();
|
||||
}
|
||||
else {
|
||||
myGrp->LineEdit1->setText(GEOMBase::GetName(myObj));
|
||||
myObjectName->setText(GEOMBase::GetName(myObj));
|
||||
|
||||
processPreview();
|
||||
}
|
||||
@ -243,9 +294,9 @@ GEOM::GEOM_IOperations_ptr MeasureGUI_GetNonBlocksDlg::createOperation()
|
||||
// function : isValid
|
||||
// purpose :
|
||||
//=================================================================================
|
||||
bool MeasureGUI_GetNonBlocksDlg::isValid (QString&)
|
||||
bool MeasureGUI_GetNonBlocksDlg::isValid (QString &msg)
|
||||
{
|
||||
return !myObj->_is_nil();
|
||||
return !myObj->_is_nil() && mySpinTol->isValid(msg, !IsPreview());
|
||||
}
|
||||
|
||||
//=================================================================================
|
||||
@ -256,7 +307,13 @@ bool MeasureGUI_GetNonBlocksDlg::execute (ObjectList& objects)
|
||||
{
|
||||
GEOM::GEOM_IBlocksOperations_var anOper = GEOM::GEOM_IBlocksOperations::_narrow(getOperation());
|
||||
GEOM::GEOM_Object_var aNonQuads;
|
||||
GEOM::GEOM_Object_var anObj = anOper->GetNonBlocks(myObj, aNonQuads);
|
||||
double aC1Tol = -1.;
|
||||
|
||||
if (myUseC1Check->isChecked()) {
|
||||
aC1Tol = mySpinTol->value();
|
||||
}
|
||||
|
||||
GEOM::GEOM_Object_var anObj = anOper->GetNonBlocks(myObj, aC1Tol, aNonQuads);
|
||||
//mainFrame()->ResultName->setText(tr("GEOM_NONBLOCKS"));
|
||||
|
||||
if (!anObj->_is_nil())
|
||||
|
@ -28,7 +28,11 @@
|
||||
|
||||
#include <GEOMBase_Skeleton.h>
|
||||
|
||||
class DlgRef_1Sel;
|
||||
class QCheckBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
class SalomeApp_DoubleSpinBox;
|
||||
|
||||
//=================================================================================
|
||||
// class : MeasureGUI_GetNonBlocksDlg
|
||||
@ -45,7 +49,7 @@ public:
|
||||
protected:
|
||||
// redefined from GEOMBase_Helper
|
||||
virtual GEOM::GEOM_IOperations_ptr createOperation();
|
||||
virtual bool isValid (QString&);
|
||||
virtual bool isValid (QString &msg);
|
||||
virtual bool execute (ObjectList&);
|
||||
virtual GEOM::GEOM_Object_ptr getFather (GEOM::GEOM_Object_ptr);
|
||||
|
||||
@ -56,6 +60,7 @@ private slots:
|
||||
void LineEditReturnPressed();
|
||||
void SelectionIntoArgument();
|
||||
void SetEditCurrentArgument();
|
||||
void SetUseC1Tolerance();
|
||||
|
||||
private:
|
||||
void Init();
|
||||
@ -64,7 +69,11 @@ private:
|
||||
|
||||
private:
|
||||
GEOM::GEOM_Object_var myObj;
|
||||
DlgRef_1Sel* myGrp;
|
||||
QLineEdit *myObjectName;
|
||||
QPushButton *mySelButton;
|
||||
QCheckBox *myUseC1Check;
|
||||
QLabel *myTolLbl;
|
||||
SalomeApp_DoubleSpinBox *mySpinTol;
|
||||
};
|
||||
|
||||
#endif // MEASUREGUI_GETNONBLOCKSDLG_H
|
||||
|
Loading…
Reference in New Issue
Block a user