--- /dev/null
+/*!
+
+\page fillet1d_operation_page Fillet 1D
+
+This operation creates fillets on the corners of a <b>Wire with Planar
+Edges</b>.
+Note, that each couple of edges connected with a vertex, where 1D fillet should be
+constructed, have to be in same plane.
+\image html fillet1d_2.png
+
+To produce a \b Fillet 1D in the <b>Main Menu</b> select
+<b>Operations - > Transformation - > Fillet 1D</b>
+
+Define the <b>Wire with planar Edges</b> to create a fillet on, select the necessary
+vertexes on this wire in the OCC Viewer and define the \b Radius of the Fillet.
+
+\b Note: This Operation Works for the Wires with <b>Planar Edges</b> Only.
+
+<b>TUI Command:</b> <em>geompy.MakeFillet1D(Shape, R, ListVertexes)</em>
+\n <b>Arguments:</b> Name + 1 shape + empty list or several vertexes + 1 value (Fillet radius).
+
+<b>Examples:</b>
+
+\image html fillet1d_1.png
+
+Our <b>TUI Scripts</b> provide you with useful examples of the use of
+\ref tui_fillet1d "Transformation Operations".
+
+*/
\b Note: This Operation Works for the <b>Planar 2D</b> Faces Only.
-<b>TUI Command:</b> <em>geompy.MakeFillet(Shape, R, ListVertexes)</em>
+<b>TUI Command:</b> <em>geompy.MakeFillet2D(Shape, R, ListVertexes)</em>
\n <b>Arguments:</b> Name + 1 shape + one or several vertexes + 1 value (Fillet radius).
<b>Examples:</b>
<li>Create a simultaneous \subpage multi_rotation_operation_page</li> "Rotation in several directions".</li>
<li>Produce a \subpage fillet_operation_page "Fillet" on the selected
edges of the object.</li>
+<li>Produce a \subpage fillet1d_operation_page "1D Fillet" on the
+corners of a Wire with Planar Edges.</li>
<li>Produce a \subpage fillet2d_operation_page "2D Fillet" on the corners of a Planar Face.</li>
<li>Produce a \subpage chamfer_operation_page "Chamfer" on the
selected edges of the object.</li>
</ul>
-*/
\ No newline at end of file
+*/
gg.createAndDisplayGO(id_fillet2d)
\endcode
+\anchor tui_fillet1d
+<br><h2>Fillet 1D</h2>
+
+\code
+import geompy
+import salome
+gg = salome.ImportComponentGUI("GEOM")
+
+# create box
+Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
+# take box edges to create custom complex wire
+[Edge_1,Edge_2,Edge_3,Edge_4,Edge_5,Edge_6,Edge_7,Edge_8,Edge_9,Edge_10,Edge_11,Edge_12] = geompy.SubShapeAllSorted(Box_1, geompy.ShapeType["EDGE"])
+# create wire
+Wire_1 = geompy.MakeWire([Edge_12, Edge_7, Edge_11, Edge_6, Edge_1,Edge_4])
+# make fillet at given wire vertices with giver radius
+Fillet_1D_1 = geompy.MakeFillet1D(Wire_1, 55, [3, 4, 6, 8, 10])
+
+
+# display disks
+gg.createAndDisplayGO(Wire_1)
+gg.createAndDisplayGO(Fillet_1D_1)
+\endcode
+
\anchor tui_fillet
<br><h2>Fillet</h2>
in double theR,
in ListOfLong theVertexes);
+ /*!
+ * Perform a fillet on edges of the specified vertexes of the given wire.
+ * \param theShape Shape, to perform fillet on.
+ * \param theR Fillet radius.
+ * \param theVertexes Global indices of vertexes to perform fillet on.
+ * \note Global index of sub-shape can be obtained, using method
+ * <VAR>GEOM_IShapesOperations.GetSubShapeIndex()</VAR>.
+ * \note The list of vertices coudl be empty, in this case fillet fill be done
+ * at all vertices in given wire
+ * \return New GEOM_Object, containing the result shape.
+ */
+ GEOM_Object MakeFillet1D (in GEOM_Object theShape,
+ in double theR,
+ in ListOfLong theVertexes);
+
/*!
* Perform a symmetric chamfer on all edges of the given shape.
* \param theShape Shape, to perform chamfer on.
face_hw.png \
face_vechw.png \
fillet.png \
+fillet1d.png \
fillet2d.png \
filletall.png \
filletedge.png \
+filletwire.png \
filletface.png \
filling.png \
fuse.png \
<source>ICON_DLG_FILLET</source>
<translation>fillet.png</translation>
</message>
+ <message>
+ <source>ICON_DLG_FILLET_1D</source>
+ <translation>fillet1d.png</translation>
+ </message>
<message>
<source>ICON_DLG_FILLET_2D</source>
<translation>fillet2d.png</translation>
<source>ICON_DLG_FILLET_EDGE</source>
<translation>filletedge.png</translation>
</message>
+ <message>
+ <source>ICON_DLG_FILLET_WIRE</source>
+ <translation>filletwire.png</translation>
+ </message>
<message>
<source>ICON_DLG_FILLET_FACE</source>
<translation>filletface.png</translation>
<source>ICO_FILLET</source>
<translation>fillet.png</translation>
</message>
+ <message>
+ <source>ICO_FILLET_1D</source>
+ <translation>fillet1d.png</translation>
+ </message>
<message>
<source>ICO_FILLET_2D</source>
<translation>fillet2d.png</translation>
<source>GEOM_FILLET_2D</source>
<translation>Fillet 2D</translation>
</message>
+ <message>
+ <source>GEOM_FILLET_1D</source>
+ <translation>Fillet 1D</translation>
+ </message>
<message>
<source>GEOM_FILLET_ABORT</source>
<translation>Fillet can't be computed with radius %1</translation>
<source>GEOM_FILLET_EDGES</source>
<translation>Fillet On Edges From Shape</translation>
</message>
+ <message>
+ <source>GEOM_FILLET_WIRES</source>
+ <translation>Fillet On Wires From Shape</translation>
+ </message>
<message>
<source>GEOM_FILLET_FACES</source>
<translation>Fillet On Faces From Shape</translation>
<source>GEOM_FILLET_2D_TITLE</source>
<translation>2D Fillet Construction</translation>
</message>
+ <message>
+ <source>GEOM_FILLET_1D_TITLE</source>
+ <translation>1D Fillet Construction</translation>
+ </message>
<message>
<source>GEOM_FILLING</source>
<translation>Filling</translation>
<source>MEN_FILLET</source>
<translation>Fillet</translation>
</message>
+ <message>
+ <source>MEN_FILLET_1D</source>
+ <translation>Fillet 1D</translation>
+ </message>
<message>
<source>MEN_FILLET_2D</source>
<translation>Fillet 2D</translation>
<source>GEOM_PLANAR_FACE</source>
<translation>Planar Face</translation>
</message>
+ <message>
+ <source>GEOM_PLANAR_EDGE_WIRE</source>
+ <translation>Wire with Planar Edges</translation>
+ </message>
<message>
<source>GEOM_POLYGON</source>
<translation>Polygon</translation>
<source>GEOM_FILLET_EDGES</source>
<translation>Cong sur Edges de la Shape</translation>
</message>
+ <message>
+ <source>GEOM_FILLET_WIRES</source>
+ <translation>Cong sur Wires de la Shape</translation>
+ </message>
<message>
<source>GEOM_FILLET_FACES</source>
<translation>Cong sur Faces de la Shape</translation>
id == 506 || // MENU OPERATION - CHAMFER
id == 507 || // MENU OPERATION - CLIPPING RANGE
id == 508 || // MENU OPERATION - GET SHAPES ON SHAPE
- id == 509 ) { // MENU OPERATION - FILLET 2D
+ id == 509 || // MENU OPERATION - FILLET 2D
+ id == 510 ) { // MENU OPERATION - FILLET 1D
#ifndef WNT
library = getLibrary( "libOperationGUI.so" );
#else
createGeomAction( 506, "CHAMFER" );
//createGeomAction( 507, "CLIPPING" );
createGeomAction( 508, "GET_SHAPES_ON_SHAPES" );
+ createGeomAction( 510, "FILLET_1D" );
createGeomAction( 509, "FILLET_2D" );
createGeomAction( 9998, "MUL_TRANSFORM" );
createMenu( 504, operId, -1 );
createMenu( 508, operId, -1 );
createMenu( separator(), operId, -1 );
+ createMenu( 510, transId, -1 );
createMenu( 509, transId, -1 );
createMenu( 505, transId, -1 );
createMenu( 506, transId, -1 );
SOURCES += GEOMImpl_SplineDriver.cxx
SOURCES += GEOMImpl_SketcherDriver.cxx
SOURCES += GEOMImpl_FilletDriver.cxx
+SOURCES += GEOMImpl_Fillet1dDriver.cxx
SOURCES += GEOMImpl_Fillet2dDriver.cxx
SOURCES += GEOMImpl_ChamferDriver.cxx
SOURCES += GEOMImpl_BooleanDriver.cxx
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : GEOMImpl_Fillet1d.cxx
+// Module : GEOMImpl
+
+#include "GEOMImpl_Fillet1d.hxx"
+
+#include <BRep_Tool.hxx>
+#include <BRepAdaptor_Curve.hxx>
+#include <BRepBuilderAPI_MakeEdge.hxx>
+#include <ElCLib.hxx>
+#include <ElSLib.hxx>
+#include <gp_Circ.hxx>
+#include <Geom2d_Line.hxx>
+#include <Geom2dAPI_ProjectPointOnCurve.hxx>
+#include <Geom2dAPI_InterCurveCurve.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomProjLib.hxx>
+#include <Geom_Circle.hxx>
+#include <Precision.hxx>
+#include <TColStd_ListIteratorOfListOfReal.hxx>
+
+/**
+ * class GEOMImpl_Fillet1d
+ */
+
+
+//=======================================================================
+//function : Constructor
+//purpose :
+//=======================================================================
+GEOMImpl_Fillet1d::GEOMImpl_Fillet1d(const TopoDS_Edge& theEdge1,
+ const TopoDS_Edge& theEdge2,
+ const gp_Pln& thePlane)
+: myEdgesExchnged( Standard_False )
+{
+ myPlane = new Geom_Plane(thePlane);
+
+ BRepAdaptor_Curve aBAC1(theEdge1);
+ BRepAdaptor_Curve aBAC2(theEdge2);
+ if (aBAC1.GetType() < aBAC2.GetType())
+ { // first curve must be more complicated
+ myEdge1 = theEdge2;
+ myEdge2 = theEdge1;
+ myEdgesExchnged = Standard_True;
+ }
+ else
+ {
+ myEdge1 = theEdge1;
+ myEdge2 = theEdge2;
+ }
+
+ Handle(Geom_Curve) aCurve1 = BRep_Tool::Curve(myEdge1, myStart1, myEnd1);
+ Handle(Geom_Curve) aCurve2 = BRep_Tool::Curve(myEdge2, myStart2, myEnd2);
+
+ myCurve1 = GeomProjLib::Curve2d(aCurve1, myStart1, myEnd1, myPlane);
+ myCurve2 = GeomProjLib::Curve2d(aCurve2, myStart2, myEnd2, myPlane);
+
+ while (myCurve1->IsPeriodic() && myStart1 >= myEnd1)
+ myEnd1 += myCurve1->Period();
+ while (myCurve2->IsPeriodic() && myStart2 >= myEnd2)
+ myEnd2 += myCurve2->Period();
+
+ if (aBAC1.GetType() == aBAC2.GetType())
+ {
+ if (myEnd2 - myStart2 < myEnd1 - myStart1)
+ { // first curve must be parametrically shorter
+ TopoDS_Edge anEdge = myEdge1;
+ myEdge1 = myEdge2;
+ myEdge2 = anEdge;
+ Handle(Geom2d_Curve) aCurve = myCurve1;
+ myCurve1 = myCurve2;
+ myCurve2 = aCurve;
+ Standard_Real a = myStart1;
+ myStart1 = myStart2;
+ myStart2 = a;
+ a = myEnd1;
+ myEnd1 = myEnd2;
+ myEnd2 = a;
+ myEdgesExchnged = Standard_True;
+ }
+ }
+}
+
+//=======================================================================
+//function : isRadiusIntersected
+//purpose : local function
+//=======================================================================
+static Standard_Boolean isRadiusIntersected(const Handle(Geom2d_Curve)& theCurve,
+ const gp_Pnt2d theStart,
+ const gp_Pnt2d theEnd,
+ const Standard_Boolean theStartConnected)
+{
+ const Standard_Real aTol = Precision::Confusion();
+ const Standard_Real anAngTol = Precision::Angular();
+ Geom2dAPI_InterCurveCurve anInter(theCurve, new Geom2d_Line(theStart,
+ gp_Dir2d(gp_Vec2d(theStart, theEnd))), aTol);
+ Standard_Integer a;
+ gp_Pnt2d aPoint;
+ for(a = anInter.NbPoints(); a > 0; a--)
+ {
+ aPoint = anInter.Point(a);
+ if (aPoint.Distance(theStart) < aTol)
+ if (!theStartConnected)
+ return Standard_True;
+ if (aPoint.Distance(theEnd) < aTol)
+ return Standard_True;
+ if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol))
+ return Standard_True;
+ }
+ Handle(Geom2d_Curve) aCurve;
+ for(a = anInter.NbSegments(); a > 0; a--)
+ {
+ anInter.Segment(a, aCurve);
+ aPoint = aCurve->Value(aCurve->FirstParameter());
+ if (aPoint.Distance(theStart) < aTol)
+ if (!theStartConnected)
+ return Standard_True;
+ if (aPoint.Distance(theEnd) < aTol)
+ return Standard_True;
+ if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol))
+ return Standard_True;
+ aPoint = aCurve->Value(aCurve->LastParameter());
+ if (aPoint.Distance(theStart) < aTol)
+ if (!theStartConnected)
+ return Standard_True;
+ if (aPoint.Distance(theEnd) < aTol)
+ return Standard_True;
+ if (gp_Vec2d(aPoint, theStart).IsOpposite(gp_Vec2d(aPoint, theEnd), anAngTol))
+ return Standard_True;
+ }
+ return Standard_False;
+}
+
+
+//=======================================================================
+//function : fillPoint
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1d::fillPoint(GEOMImpl_Fillet1dPoint* thePoint)
+{
+ gp_Pnt2d aPoint;
+ gp_Vec2d aVec;
+ const Standard_Real aTol = Precision::Confusion();
+ myCurve1->D1(thePoint->GetParam(), aPoint, aVec);
+ if (aVec.SquareMagnitude() < aTol)
+ return;
+
+ gp_Vec2d aPerp(((myStartSide)?-1:1) * aVec.Y(), ((myStartSide)?1:-1) * aVec.X());
+ aPerp.Normalize();
+ aPerp.Multiply(myRadius);
+ gp_Pnt2d aCenter = aPoint.Translated(aPerp);
+ thePoint->SetCenter(aCenter);
+
+ // on the intersection point
+ Standard_Boolean aValid = Standard_True;
+ Geom2dAPI_ProjectPointOnCurve aProjInt(aPoint, myCurve2);
+ if (aProjInt.NbPoints() && aPoint.Distance(aProjInt.NearestPoint()) < aTol)
+ aValid = Standard_False;
+ else
+ aValid = !isRadiusIntersected(myCurve2, aPoint, aCenter, Standard_True);
+
+ Geom2dAPI_ProjectPointOnCurve aProj(aCenter, myCurve2);
+ Standard_Integer a, aNB = aProj.NbPoints();
+ for(a = aNB; a > 0; a--)
+ {
+ if (aPoint.Distance(aProj.Point(a)) < aTol)
+ continue;
+
+ Standard_Boolean aValid2 = aValid;
+ if (aValid2)
+ aValid2 = !isRadiusIntersected(myCurve1, aCenter, aProj.Point(a), Standard_False);
+
+ // checking the right parameter
+ Standard_Real aParam = aProj.Parameter(a);
+ while(myCurve2->IsPeriodic() && aParam < myStart2)
+ aParam += myCurve2->Period();
+
+ thePoint->AddValue(aProj.Distance(a) * aProj.Distance(a) - myRadius * myRadius,
+ (aParam >= myStart2 && aParam <= myEnd2 && aValid2));
+ if (fabs(fabs(aProj.Distance(a)) - myRadius) < aTol)
+ thePoint->SetParam2(aParam);
+ }
+}
+
+//=======================================================================
+//function : fillDiff
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1d::fillDiff(GEOMImpl_Fillet1dPoint* thePoint, Standard_Real theDiffStep, Standard_Boolean theFront)
+{
+ GEOMImpl_Fillet1dPoint* aDiff =
+ new GEOMImpl_Fillet1dPoint(thePoint->GetParam() + (theFront?(theDiffStep):(-theDiffStep)));
+ fillPoint(aDiff);
+ if (!thePoint->ComputeDifference(aDiff))
+ {
+ aDiff->SetParam(thePoint->GetParam() + (theFront?(-theDiffStep):(theDiffStep)));
+ fillPoint(aDiff);
+ thePoint->ComputeDifference(aDiff);
+ }
+ delete aDiff;
+}
+
+//=======================================================================
+//function : Perform
+//purpose :
+//=======================================================================
+Standard_Boolean GEOMImpl_Fillet1d::Perform(const Standard_Real theRadius)
+{
+ myResultParams.Clear();
+ myResultOrientation.Clear();
+
+ Standard_Real aNBSteps = 100;
+ Geom2dAdaptor_Curve aGAC(myCurve1);
+ switch (aGAC.GetType())
+ {
+ case GeomAbs_Line:
+ aNBSteps = 2;
+ break;
+ case GeomAbs_Circle:
+ aNBSteps = 4;
+ break;
+ case GeomAbs_Ellipse:
+ aNBSteps = 5;
+ break;
+ case GeomAbs_BezierCurve:
+ case GeomAbs_BSplineCurve:
+ aNBSteps = 2 + aGAC.Degree() * aGAC.NbPoles();
+ break;
+ default: // unknown: maximum
+ aNBSteps = 100;
+ }
+
+ myRadius = theRadius;
+ Standard_Real aParam, aStep, aDStep;
+ aStep = (myEnd1 - myStart1) / aNBSteps;
+ aDStep = aStep/1000.;
+
+ Standard_Integer aCycle;
+ for(aCycle = 2, myStartSide = Standard_False; aCycle; myStartSide = !myStartSide, aCycle--)
+ {
+ GEOMImpl_Fillet1dPoint *aLeft = NULL, *aRight = NULL;
+
+ for(aParam = myStart1 + aStep; aParam < myEnd1 || fabs(myEnd1 - aParam) < Precision::Confusion(); aParam += aStep)
+ {
+ if (!aLeft)
+ {
+ aLeft = new GEOMImpl_Fillet1dPoint(aParam - aStep);
+ fillPoint(aLeft);
+ fillDiff(aLeft, aDStep, Standard_True);
+ }
+
+ aRight = new GEOMImpl_Fillet1dPoint(aParam);
+ fillPoint(aRight);
+ fillDiff(aRight, aDStep, Standard_False);
+
+ aLeft->FilterPoints(aRight);
+ performNewton(aLeft, aRight);
+
+ delete aLeft;
+ aLeft = aRight;
+ }
+ delete aLeft;
+ }
+
+ if (myResultParams.Extent())
+ return Standard_True;
+
+ return Standard_False;
+}
+
+//=======================================================================
+//function : processPoint
+//purpose :
+//=======================================================================
+Standard_Boolean GEOMImpl_Fillet1d::processPoint(GEOMImpl_Fillet1dPoint* theLeft,
+ GEOMImpl_Fillet1dPoint* theRight,
+ Standard_Real theParameter)
+{
+ if (theParameter >= theLeft->GetParam() && theParameter < theRight->GetParam())
+ {
+ Standard_Real aDX = theRight->GetParam() - theLeft->GetParam();
+ if (theParameter - theLeft->GetParam() < aDX / 100.)
+ {
+ theParameter = theLeft->GetParam() + aDX / 100.;
+ }
+ if (theRight->GetParam() - theParameter < aDX / 100.)
+ {
+ theParameter = theRight->GetParam() - aDX / 100.;
+ }
+
+ GEOMImpl_Fillet1dPoint* aPoint1 = theLeft->Copy();
+ GEOMImpl_Fillet1dPoint* aPoint2 = new GEOMImpl_Fillet1dPoint(theParameter);
+ fillPoint(aPoint2);
+ fillDiff(aPoint2, aDX / 1000., Standard_True);
+
+ aPoint1->FilterPoints(aPoint2);
+ performNewton(aPoint1, aPoint2);
+ aPoint2->FilterPoints(theRight);
+ performNewton(aPoint2, theRight);
+
+ delete aPoint1;
+ delete aPoint2;
+ return Standard_True;
+ }
+
+ return Standard_False;
+}
+
+//=======================================================================
+//function : performNewton
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1d::performNewton(GEOMImpl_Fillet1dPoint* theLeft,
+ GEOMImpl_Fillet1dPoint* theRight)
+{
+ Standard_Integer a;
+ // check the left: if this is solution store it and remove it from the list of researching points of theLeft
+ a = theLeft->HasSolution(myRadius);
+ if (a)
+ {
+ if (theLeft->IsValid(a))
+ {
+ myResultParams.Append(theLeft->GetParam());
+ myResultOrientation.Append(myStartSide);
+ }
+ return;
+ }
+
+ Standard_Real aDX = theRight->GetParam() - theLeft->GetParam();
+ if (aDX < gp::Resolution()/*Precision::Confusion() / 1000000.*/)
+ {
+ a = theRight->HasSolution(myRadius);
+ if (a)
+ if (theRight->IsValid(a))
+ {
+ myResultParams.Append(theRight->GetParam());
+ myResultOrientation.Append(myStartSide);
+ }
+ return;
+ }
+
+ for(a = 1; a <= theLeft->GetNBValues(); a++)
+ {
+ Standard_Integer aNear = theLeft->GetNear(a);
+
+ Standard_Real aA = (theRight->GetDiff(aNear) - theLeft->GetDiff(a)) / aDX;
+ Standard_Real aB = theLeft->GetDiff(a) - aA * theLeft->GetParam();
+ Standard_Real aC = theLeft->GetValue(a) - theLeft->GetDiff(a) * theLeft->GetParam() +
+ aA * theLeft->GetParam() * theLeft->GetParam() / 2.0;
+ Standard_Real aDet = aB * aB - 2.0 * aA * aC;
+
+ if (fabs(aA) < Precision::Confusion())
+ { // linear case
+ if (fabs(aB) > 10e-20)
+ {
+ Standard_Real aX0 = - aC / aB; // use extremum
+ if (aX0 > theLeft->GetParam() && aX0 < theRight->GetParam())
+ processPoint(theLeft, theRight, aX0);
+ }
+ else
+ {
+ processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
+ }
+ }
+ else
+ {
+ if (fabs(aB) > fabs(aDet * 1000000.))
+ { // possible floating point operations accurancy errors
+ processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
+ }
+ else
+ {
+ if (aDet > 0)
+ { // two solutions
+ aDet = sqrt(aDet);
+ Standard_Boolean aRes = processPoint(theLeft, theRight, (- aB + aDet) / aA);
+ if (!aRes)
+ aRes = processPoint(theLeft, theRight, (- aB - aDet) / aA);
+ if (!aRes)
+ processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
+ }
+ else
+ {
+ Standard_Real aX0 = - aB / aA; // use extremum
+ if (aX0 > theLeft->GetParam() && aX0 < theRight->GetParam())
+ processPoint(theLeft, theRight, aX0);
+ else
+ processPoint(theLeft, theRight, theLeft->GetParam() + aDX / 2.0); // linear division otherwise
+ }
+ }
+ }
+ }
+}
+
+//=======================================================================
+//function : Result
+//purpose :
+//=======================================================================
+TopoDS_Edge GEOMImpl_Fillet1d::Result(const gp_Pnt& thePoint,
+ TopoDS_Edge& theEdge1,
+ TopoDS_Edge& theEdge2)
+{
+ TopoDS_Edge aResult;
+ gp_Pnt2d aTargetPoint2d;
+ Standard_Real aX, aY;
+ ElSLib::PlaneParameters(myPlane->Pln().Position(), thePoint, aX, aY);
+ aTargetPoint2d.SetCoord(aX, aY);
+
+ // choose the nearest circle
+ Standard_Real aDistance, aP;
+ GEOMImpl_Fillet1dPoint *aNearest;
+ Standard_Integer a;
+ TColStd_ListIteratorOfListOfReal anIter(myResultParams);
+ for(aNearest = NULL, a = 1; anIter.More(); anIter.Next(), a++)
+ {
+ myStartSide = (myResultOrientation.Value(a)) ? Standard_True : Standard_False;
+ GEOMImpl_Fillet1dPoint *aPoint = new GEOMImpl_Fillet1dPoint(anIter.Value());
+ fillPoint(aPoint);
+ if (!aPoint->HasSolution(myRadius))
+ continue;
+ aP = fabs(aPoint->GetCenter().Distance(aTargetPoint2d) - myRadius);
+ if (!aNearest || aP < aDistance)
+ {
+ aNearest = aPoint;
+ aDistance = aP;
+ }
+ else
+ {
+ delete aPoint;
+ }
+ }
+
+ if (!aNearest)
+ return aResult;
+
+ // create circle edge
+ gp_Pnt aCenter = ElSLib::PlaneValue(aNearest->GetCenter().X(),
+ aNearest->GetCenter().Y(),
+ myPlane->Pln().Position());
+ Handle(Geom_Circle) aCircle =
+ new Geom_Circle(gp_Ax2(aCenter, myPlane->Pln().Axis().Direction()), myRadius);
+ gp_Pnt2d aPoint2d1, aPoint2d2;
+ myCurve1->D0(aNearest->GetParam(), aPoint2d1);
+ myCurve2->D0(aNearest->GetParam2(), aPoint2d2);
+ gp_Pnt aPoint1 = ElSLib::PlaneValue(aPoint2d1.X(), aPoint2d1.Y(), myPlane->Pln().Position());
+ gp_Pnt aPoint2 = ElSLib::PlaneValue(aPoint2d2.X(), aPoint2d2.Y(), myPlane->Pln().Position());
+
+ GeomAPI_ProjectPointOnCurve aProj(thePoint, aCircle);
+ Standard_Real aTarGetParam = aProj.LowerDistanceParameter();
+ gp_Pnt aPointOnCircle = aProj.NearestPoint();
+
+ // Check extrema point manually, because there is a bug in Open CASCADE
+ // in calculation of nearest point to a circle near the parameter 0.0
+ gp_Pnt p0 = ElCLib::Value(0.0, aCircle->Circ());
+ if (p0.Distance(thePoint) < aPointOnCircle.Distance(thePoint))
+ {
+ aTarGetParam = 0.0;
+ aPointOnCircle = p0;
+ }
+
+ aProj.Perform(aPoint1);
+ Standard_Real aParam1 = aProj.LowerDistanceParameter();
+ aProj.Perform(aPoint2);
+ Standard_Real aParam2 = aProj.LowerDistanceParameter();
+ Standard_Boolean aIsOut = ((aParam1 < aTarGetParam && aParam2 < aTarGetParam) ||
+ (aParam1 > aTarGetParam && aParam2 > aTarGetParam));
+ if (aParam1 > aParam2)
+ aIsOut = !aIsOut;
+ BRepBuilderAPI_MakeEdge aBuilder(aCircle->Circ(),
+ aIsOut ? aParam2 : aParam1,
+ aIsOut? aParam1 : aParam2);
+ aResult = aBuilder.Edge();
+
+ // divide edges
+ Standard_Real aStart, anEnd;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(myEdge1, aStart, anEnd);
+ gp_Vec aDir;
+ aCurve->D1(aNearest->GetParam(), aPoint1, aDir);
+
+ gp_Vec aCircleDir;
+ aCircle->D1(aParam1, aPoint1, aCircleDir);
+ if ((aCircleDir.Angle(aDir) > PI / 2.0) ^ aIsOut)
+ aStart = aNearest->GetParam();
+ else
+ anEnd = aNearest->GetParam();
+
+ //Check the case when start and end are identical. This happens
+ //when the edge decreases to size 0. Old ww5 allows such
+ //cases. So we are again bug compatible
+ if (fabs(aStart - anEnd) < Precision::PConfusion()/*gp::Resolution()*/)
+ anEnd = 0.01;
+ //Divide edge
+ BRepBuilderAPI_MakeEdge aDivider1(aCurve, aStart, anEnd);
+ if (myEdgesExchnged)
+ theEdge2 = aDivider1.Edge();
+ else
+ theEdge1 = aDivider1.Edge();
+
+
+ aCurve = BRep_Tool::Curve(myEdge2, aStart, anEnd);
+ aCurve->D1(aNearest->GetParam2(), aPoint2, aDir);
+
+ aCircle->D1(aParam2, aPoint2, aCircleDir);
+ if ((aCircleDir.Angle(aDir) > PI / 2.0) ^ (!aIsOut))
+ aStart = aNearest->GetParam2();
+ else
+ anEnd = aNearest->GetParam2();
+
+ //Check the case when start and end are identical. This happens
+ //when the edge decreases to size 0. Old ww5 allows such
+ //cases. So we are again bug compatible
+ if (fabs(aStart - anEnd) < Precision::PConfusion()/*gp::Resolution()*/)
+ anEnd = 0.01;
+ BRepBuilderAPI_MakeEdge aDivider2(aCurve, aStart, anEnd);
+ if (myEdgesExchnged)
+ theEdge1 = aDivider2.Edge();
+ else
+ theEdge2 = aDivider2.Edge();
+
+ delete aNearest;
+ return aResult;
+}
+
+//=======================================================================
+//function : AddValue
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1dPoint::AddValue(Standard_Real theValue, Standard_Boolean theValid)
+{
+ Standard_Integer a;
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ if (theValue < myV.Value(a))
+ {
+ myV.InsertBefore(a, theValue);
+ myValid.InsertBefore(a, (Standard_Integer)theValid);
+ return;
+ }
+ }
+ myV.Append(theValue);
+ myValid.Append((Standard_Integer)theValid);
+}
+
+//=======================================================================
+//function : ComputeDifference
+//purpose :
+//=======================================================================
+Standard_Boolean GEOMImpl_Fillet1dPoint::ComputeDifference(GEOMImpl_Fillet1dPoint* thePoint)
+{
+ Standard_Integer a;
+ Standard_Boolean aDiffsSet = (myD.Length() != 0);
+ Standard_Real aDX = thePoint->GetParam() - myParam, aDY;
+ if (thePoint->myV.Length() == myV.Length())
+ { // absolutely the same points
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ aDY = thePoint->myV.Value(a) - myV.Value(a);
+ if (aDiffsSet)
+ myD.SetValue(a, aDY / aDX);
+ else
+ myD.Append(aDY / aDX);
+ }
+ return Standard_True;
+ }
+ // between the diffeerent points searching for nearest analogs
+ Standard_Integer b;
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ for(b = 1; b <= thePoint->myV.Length(); b++)
+ {
+ if (b == 1 || fabs(thePoint->myV.Value(b) - myV.Value(a)) < fabs(aDY))
+ aDY = thePoint->myV.Value(b) - myV.Value(a);
+ }
+ if (aDiffsSet)
+ {
+ if (fabs(aDY / aDX) < fabs(myD.Value(a)))
+ myD.SetValue(a, aDY / aDX);
+ }
+ else
+ {
+ myD.Append(aDY / aDX);
+ }
+ }
+
+ return Standard_False;
+}
+
+//=======================================================================
+//function : FilterPoints
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1dPoint::FilterPoints(GEOMImpl_Fillet1dPoint* thePoint)
+{
+ Standard_Integer a, b;
+ TColStd_SequenceOfReal aDiffs;
+ Standard_Real aY, aY2, aDX = thePoint->GetParam() - myParam;
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ // searching for near point from thePoint
+ Standard_Integer aNear = 0;
+ Standard_Real aDiff = aDX * 10000.;
+ aY = myV.Value(a) + myD.Value(a) * aDX;
+ for(b = 1; b <= thePoint->myV.Length(); b++)
+ {
+ // calculate hypothesis value of the Y2 with the constant first and second derivative
+ aY2 = aY + aDX * (thePoint->myD.Value(b) - myD.Value(a)) / 2.0;
+ if (aNear == 0 || fabs(aY2 - thePoint->myV.Value(b)) < fabs(aDiff))
+ {
+ aNear = b;
+ aDiff = aY2 - thePoint->myV.Value(b);
+ }
+ }//for b...
+
+ if (aNear)
+ {
+ if (myV.Value(a) * thePoint->myV.Value(aNear) > 0)
+ {// the same sign at the same sides of the interval
+ if (myV.Value(a) * myD.Value(a) > 0)
+ {
+ if (fabs(myD.Value(a)) > Precision::Confusion())
+ aNear = 0;
+ }
+ else
+ {
+ if (fabs(myV.Value(a)) > fabs(thePoint->myV.Value(aNear)))
+ if (thePoint->myV.Value(aNear) * thePoint->myD.Value(aNear) < 0 &&
+ fabs(thePoint->myD.Value(aNear)) > Precision::Confusion())
+ {
+ aNear = 0;
+ }
+ }
+ }
+ }
+
+ if (aNear)
+ {
+ if (myV.Value(a) * thePoint->myV.Value(aNear) > 0)
+ {
+ if ((myV.Value(a) + myD.Value(a) * aDX) * myV.Value(a) > Precision::Confusion() &&
+ (thePoint->myV.Value(aNear) + thePoint->myD.Value(aNear) * aDX) * thePoint->myV.Value(aNear) > Precision::Confusion())
+ {
+ aNear = 0;
+ }
+ }
+ }
+
+ if (aNear)
+ {
+ if (fabs(aDiff / aDX) > 1.e+7)
+ {
+ aNear = 0;
+ }
+ }
+
+ if (aNear == 0)
+ { // there is no near: remove it from the list
+ myV.Remove(a);
+ myD.Remove(a);
+ myValid.Remove(a);
+ a--;
+ }
+ else
+ {
+ Standard_Boolean aFound = Standard_False;
+ for(b = 1; b <= myNear.Length(); b++)
+ {
+ if (myNear.Value(b) == aNear)
+ {
+ if (fabs(aDiffs.Value(b)) < fabs(aDiff))
+ { // return this 'near'
+ aFound = Standard_True;
+ myV.Remove(a);
+ myD.Remove(a);
+ myValid.Remove(a);
+ a--;
+ break;
+ }
+ else
+ { // remove the old 'near'
+ myV.Remove(b);
+ myD.Remove(b);
+ myValid.Remove(b);
+ myNear.Remove(b);
+ aDiffs.Remove(b);
+ a--;
+ break;
+ }
+ }
+ }//for b...
+ if (!aFound)
+ {
+ myNear.Append(aNear);
+ aDiffs.Append(aDiff);
+ }
+ }
+ }//for a...
+}
+
+//=======================================================================
+//function : Copy
+//purpose :
+//=======================================================================
+GEOMImpl_Fillet1dPoint* GEOMImpl_Fillet1dPoint::Copy()
+{
+ GEOMImpl_Fillet1dPoint* aCopy = new GEOMImpl_Fillet1dPoint(myParam);
+ Standard_Integer a;
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ aCopy->myV.Append(myV.Value(a));
+ aCopy->myD.Append(myD.Value(a));
+ aCopy->myValid.Append(myValid.Value(a));
+ }
+ return aCopy;
+}
+
+//=======================================================================
+//function : HasSolution
+//purpose :
+//=======================================================================
+Standard_Integer GEOMImpl_Fillet1dPoint::HasSolution(const Standard_Real theRadius)
+{
+ Standard_Integer a;
+ for(a = 1; a <= myV.Length(); a++)
+ {
+ if (fabs(sqrt(fabs(fabs(myV.Value(a)) + theRadius * theRadius)) - theRadius) < Precision::Confusion() / 10.)
+ return a;
+ }
+ return 0;
+}
+
+//=======================================================================
+//function : RemoveSolution
+//purpose :
+//=======================================================================
+void GEOMImpl_Fillet1dPoint::RemoveSolution(Standard_Integer theIndex)
+{
+ myV.Remove(theIndex);
+ myD.Remove(theIndex);
+ myValid.Remove(theIndex);
+ myNear.Remove(theIndex);
+}
--- /dev/null
+// Copyright (C) 2009 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : GEOMImpl_Fillet1d.hxx
+// Module : GEOMImpl
+
+#ifndef _GEOMImpl_Fillet1d_HeaderFile
+#define _GEOMImpl_Fillet1d_HeaderFile
+
+#include <gp_Pnt.hxx>
+#include <Geom_Plane.hxx>
+#include <Geom2d_Curve.hxx>
+
+#include <TopoDS_Edge.hxx>
+#include <TColStd_ListOfReal.hxx>
+#include <TColStd_SequenceOfReal.hxx>
+#include <TColStd_SequenceOfInteger.hxx>
+
+class GEOMImpl_Fillet1dPoint;
+
+/**
+* GEOMImpl_Fillet1d is 1D fillet algorithm on two planar edges with given radius
+*/
+
+class GEOMImpl_Fillet1d
+{
+public:
+ //! Constructor
+ //! The fillet 1D algorithm initialise by two edges and plane
+ Standard_EXPORT GEOMImpl_Fillet1d(const TopoDS_Edge& theEdge1,
+ const TopoDS_Edge& theEdge2,
+ const gp_Pln& thePlane);
+ //! Makes fillet with given radius
+ //! @returns Standard_True, if at least one result computed
+ Standard_EXPORT Standard_Boolean Perform(const Standard_Real theRadius);
+ //! Returns result fillet edge and modified edges as out parameters
+ Standard_EXPORT TopoDS_Edge Result(const gp_Pnt& thePoint, TopoDS_Edge& theEdge1, TopoDS_Edge& theEdge2);
+
+private:
+ //! private methods
+ void fillPoint(GEOMImpl_Fillet1dPoint*);
+ void fillDiff(GEOMImpl_Fillet1dPoint*, Standard_Real, Standard_Boolean);
+ void performNewton(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*);
+ Standard_Boolean processPoint(GEOMImpl_Fillet1dPoint*, GEOMImpl_Fillet1dPoint*, Standard_Real);
+
+
+private:
+ //! private fields
+ TopoDS_Edge myEdge1, myEdge2;
+ Handle(Geom_Plane) myPlane;
+ Handle(Geom2d_Curve) myCurve1, myCurve2;
+ Standard_Real myStart1, myEnd1, myStart2, myEnd2, myRadius;
+ TColStd_ListOfReal myResultParams;
+ TColStd_SequenceOfInteger myResultOrientation;
+ Standard_Boolean myStartSide, myEdgesExchnged;
+};
+
+
+/**
+* GEOMImpl_Fillet1dPoint is an internal class for 1D fillet algorithm
+* to store and compare computed solutions on edges
+*/
+
+class GEOMImpl_Fillet1dPoint
+{
+public:
+ //! Puiblic methods
+
+ //! Constructor
+ Standard_EXPORT GEOMImpl_Fillet1dPoint(Standard_Real theParam)
+ {myParam = theParam;}
+
+ //! Make copy of point
+ //!WARNING: Copies only field values: myParam, myV, myD, myValid
+ Standard_EXPORT GEOMImpl_Fillet1dPoint* Copy(); // warning: this is not the full copy!
+
+ //! Set/Get parameter
+ Standard_EXPORT inline void SetParam(Standard_Real theParam)
+ {myParam = theParam;}
+ Standard_EXPORT inline Standard_Real GetParam() const
+ {return myParam;}
+ Standard_EXPORT inline void SetParam2(const Standard_Real theParam2)
+ {myParam2 = theParam2;}
+ Standard_EXPORT inline Standard_Real GetParam2()
+ { return myParam2 ; }
+
+ //! Returns validity
+ Standard_EXPORT inline Standard_Boolean IsValid(int theIndex)
+ {return (Standard_Boolean)myValid.Value(theIndex);}
+
+ //! Get values
+ Standard_EXPORT inline Standard_Integer GetNBValues() {return myV.Length();}
+ Standard_EXPORT inline Standard_Real GetValue(Standard_Integer theIndex)
+ {return myV.Value(theIndex);}
+ Standard_EXPORT inline Standard_Real GetDiff(Standard_Integer theIndex)
+ {return myD.Value(theIndex);}
+ Standard_EXPORT inline Standard_Integer GetNear(Standard_Integer theIndex)
+ {return myNear.Value(theIndex);}
+
+ //! Set/Get center point
+ Standard_EXPORT inline void SetCenter(const gp_Pnt2d thePoint)
+ {myCenter = thePoint;}
+ Standard_EXPORT inline const gp_Pnt2d GetCenter()
+ {return myCenter;}
+
+ Standard_EXPORT void AddValue(Standard_Real theValue, Standard_Boolean theIsValid);
+
+ //! compute difference between this and given point
+ Standard_EXPORT Standard_Boolean ComputeDifference(GEOMImpl_Fillet1dPoint*);
+ Standard_EXPORT void FilterPoints(GEOMImpl_Fillet1dPoint*);
+
+ //! Check is point contains solution and returns the index of them if any
+ Standard_EXPORT Standard_Integer HasSolution(Standard_Real theRadius);
+ //! Remove solution by index
+ void RemoveSolution(Standard_Integer theIndex);
+
+private:
+ //! Private fields
+ gp_Pnt2d myCenter;
+ Standard_Real myParam, myParam2;
+ TColStd_SequenceOfReal myV, myD;
+ TColStd_SequenceOfInteger myValid, myNear;
+};
+
+#endif
--- /dev/null
+// Copyright (C) 2009 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include <Standard_Stream.hxx>
+
+#include <GEOMImpl_Fillet1dDriver.hxx>
+
+#include <GEOMImpl_Fillet1d.hxx>
+#include <GEOMImpl_IFillet1d.hxx>
+#include <GEOMImpl_Types.hxx>
+#include <GEOMImpl_ILocalOperations.hxx>
+#include <GEOM_Function.hxx>
+
+#include <gp_Pln.hxx>
+#include <gp_Dir.hxx>
+#include <gp_XYZ.hxx>
+
+#include <BRep_Tool.hxx>
+#include <BRepTools.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepCheck_Analyzer.hxx>
+
+#include <Precision.hxx>
+
+#include <ShapeFix_Wire.hxx>
+#include <StdFail_NotDone.hxx>
+#include <Standard_ConstructionError.hxx>
+
+#include <TopAbs.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+
+//=======================================================================
+//function : GetID
+//purpose :
+//=======================================================================
+const Standard_GUID& GEOMImpl_Fillet1dDriver::GetID()
+{
+ static Standard_GUID aFillet1dDriver("FF60908B-AB2E-4b71-B098-5C256C37D961");
+ return aFillet1dDriver;
+}
+
+//=======================================================================
+//function : GEOMImpl_Fillet1dDriver
+//purpose :
+//=======================================================================
+GEOMImpl_Fillet1dDriver::GEOMImpl_Fillet1dDriver()
+{
+}
+
+//=======================================================================
+//function : anotherVertex
+//purpose : local function to get vertex from edge
+//=======================================================================
+static TopoDS_Vertex anotherVertex( const TopoDS_Edge& theE,
+ const TopoDS_Vertex& theV )
+{
+ // here is an assumption that edge has different vertices
+ TopoDS_Vertex aV;
+ TopExp_Explorer anExp( theE, TopAbs_VERTEX );
+ for ( ; anExp.More(); anExp.Next() )
+ {
+ if ( BRepTools::Compare(theV,TopoDS::Vertex(anExp.Current())) /*theV.IsSame(anExp.Current())*/ )
+ continue;
+ aV = TopoDS::Vertex( anExp.Current() );
+ break;
+ }
+ return aV;
+}
+
+//=======================================================================
+//function : takePlane
+//purpose : local function returns plane of given edges
+//=======================================================================
+static Standard_Boolean takePlane( const TopoDS_Edge& theE1,
+ const TopoDS_Edge& theE2,
+ const TopoDS_Vertex& theV,
+ gp_Pln& thePlane )
+{
+ TopoDS_Vertex aV12 = anotherVertex( theE1, theV );
+ TopoDS_Vertex aV22 = anotherVertex( theE2, theV );
+ // check can closed wire be created by two initial edges
+ if ( aV12.IsNull() || aV22.IsNull() || aV12.IsSame( aV22 ) )
+ return false;
+
+ // create plane by 3 points
+ gp_XYZ aXYZ = BRep_Tool::Pnt( theV ).XYZ();
+ gp_XYZ aXYZ1 = BRep_Tool::Pnt( aV12 ).XYZ();
+ gp_XYZ aXYZ2 = BRep_Tool::Pnt( aV22 ).XYZ();
+ try {
+ gp_Dir aDir1( aXYZ - aXYZ1 );
+ gp_Dir aDir2( aXYZ2 - aXYZ );
+ Standard_Real anAngle = aDir1.Angle(aDir2);
+ if ( fabs(anAngle) <= gp::Resolution() ||
+ fabs(anAngle - PI) <= gp::Resolution() )
+ return false;
+ //thePlane = gp_Pln( gp_Pnt(aXYZ), aDir1^ aDir2);
+ thePlane = gp_Pln( gp_Pnt(aXYZ), gp_Dir(0,0,1));
+ }
+ catch (Standard_Failure) {
+ return false;
+ }
+ return true;
+}
+
+//=======================================================================
+//function : addEdgeRelation
+//purpose : local function to remember relation between initial and modified edge
+//=======================================================================
+static void addEdgeRelation(TopTools_DataMapOfShapeShape& theMap,
+ const TopoDS_Edge& theInitE,
+ const TopoDS_Edge& theResE)
+{
+ if ( theMap.IsBound( theInitE ) )
+ theMap.ChangeFind( theInitE ) = theResE;
+ else
+ theMap.Bind( theInitE, theResE );
+}
+
+//=======================================================================
+//function : Execute
+//purpose :
+//=======================================================================
+Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const
+{
+ if (Label().IsNull()) return 0;
+ Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
+
+ GEOMImpl_IFillet1d aCI (aFunction);
+
+ Handle(GEOM_Function) aRefShape = aCI.GetShape();
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (aShape.ShapeType() != TopAbs_WIRE)
+ Standard_ConstructionError::Raise("Wrong arguments: polyline as wire must be given");
+
+ TopoDS_Wire aWire = TopoDS::Wire(aShape);
+
+ double rad = aCI.GetR();
+
+ // collect vertices for make fillet
+ TopTools_ListOfShape aVertexList;
+ int aLen = aCI.GetLength();
+ if ( aLen > 0 )
+ {
+ for (int ind = 1; ind <= aLen; ind++) {
+ TopoDS_Shape aShapeVertex;
+ if (GEOMImpl_ILocalOperations::GetSubShape
+ (aWire, aCI.GetVertex(ind), aShapeVertex))
+ aVertexList.Append( aShapeVertex );
+ }
+ }
+ else
+ {
+ // get all vertices from wire
+ TopExp_Explorer anExp( aWire, TopAbs_VERTEX );
+ for ( ; anExp.More(); anExp.Next() )
+ aVertexList.Append( anExp.Current() );
+ }
+ if (aVertexList.IsEmpty())
+ Standard_ConstructionError::Raise("Invalid input no vertices to make fillet");
+
+ bool res = false;
+ //INFO: this algorithm implemented in assumption that user can select both
+ // vertices of some edges to make fillet. In this case we should remember
+ // already modified initial edges to take care in next fillet step
+ TopTools_DataMapOfShapeShape anEdgeToEdgeMap;
+
+ //iterates on vertices, and make fillet on each couple of edges
+ //collect result fillet edges in list
+ TopTools_ListOfShape aListOfNewEdge;
+ // remember relation between initial and modified map
+ TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges;
+ TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges );
+ TopTools_ListIteratorOfListOfShape anIt( aVertexList );
+ for ( ; anIt.More(); anIt.Next() )
+ {
+ TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() );
+ if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) )
+ continue;
+ const TopTools_ListOfShape& aVertexEdges = aMapVToEdges.FindFromKey( aV );
+ if ( aVertexEdges.Extent() != 2 )
+ continue; // no input data to make fillet
+ TopoDS_Edge anEdge1 = TopoDS::Edge( aVertexEdges.First() );
+ TopoDS_Edge anEdge2 = TopoDS::Edge( aVertexEdges.Last() );
+ // check if initial edges already modified in previous fillet operation
+ if ( anEdgeToEdgeMap.IsBound( anEdge1 ) ) anEdge1 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge1 ));
+ if ( anEdgeToEdgeMap.IsBound( anEdge2 ) ) anEdge2 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge2 ));
+ if ( anEdge1.IsNull() || anEdge2.IsNull() || anEdge1.IsSame( anEdge2 ) )
+ continue; //no input data to make fillet
+
+ // create plane on 2 edges
+ gp_Pln aPlane;
+ if ( !takePlane(anEdge1, anEdge2, aV, aPlane) )
+ continue; // seems edges does not belong to same plane or parallel (fillet can not be build)
+
+ GEOMImpl_Fillet1d aFilletAlgo(anEdge1, anEdge2, aPlane);
+ if ( !aFilletAlgo.Perform(rad) )
+ continue; // can not create fillet with given radius
+
+ // take fillet result in given vertex
+ TopoDS_Edge aModifE1, aModifE2;
+ TopoDS_Edge aNewE = aFilletAlgo.Result(BRep_Tool::Pnt(aV), aModifE1, aModifE2);
+ if (aNewE.IsNull())
+ continue; // no result found
+
+ res |= true;
+ // add new created edges and take modified edges
+ aListOfNewEdge.Append( aNewE );
+
+ // check if face edges modified,
+ // if yes, than map to original edges (from vertex-edges list), because edges can be modified before
+ if (!aModifE1.IsNull() || !aModifE1.IsSame( anEdge1 ))
+ addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 );
+ if (!aModifE2.IsNull() || !aModifE2.IsSame( anEdge2 ))
+ addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 );
+ }
+
+ if ( !res && anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() )
+ {
+ StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius");
+ return 0; // nothing done :(
+ }
+
+ // create new wire instead of original
+ for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() )
+ {
+ TopoDS_Shape anEdge = anExp.Current();
+ if ( !anEdgeToEdgeMap.IsBound( anEdge ) )
+ aListOfNewEdge.Append( anEdge );
+ else
+ aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) );
+ }
+ BRepBuilderAPI_MakeWire aWireTool;
+ aWireTool.Add( aListOfNewEdge );
+ aWireTool.Build();
+ if (!aWireTool.IsDone())
+ return 0;
+
+ aWire = aWireTool.Wire();
+ aFunction->SetValue(aWire);
+ log.SetTouched(Label());
+
+ return 1;
+}
+
+
+//=======================================================================
+//function : GEOMImpl_Fillet1dDriver_Type_
+//purpose :
+//=======================================================================
+Standard_EXPORT Handle_Standard_Type& GEOMImpl_Fillet1dDriver_Type_()
+{
+
+ static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
+ if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
+ static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
+ if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
+ static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
+ if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
+
+
+ static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
+ static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_Fillet1dDriver",
+ sizeof(GEOMImpl_Fillet1dDriver),
+ 1,
+ (Standard_Address)_Ancestors,
+ (Standard_Address)NULL);
+
+ return _aType;
+}
+
+//=======================================================================
+//function : DownCast
+//purpose :
+//=======================================================================
+const Handle(GEOMImpl_Fillet1dDriver) Handle(GEOMImpl_Fillet1dDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
+{
+ Handle(GEOMImpl_Fillet1dDriver) _anOtherObject;
+
+ if (!AnObject.IsNull()) {
+ if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_Fillet1dDriver))) {
+ _anOtherObject = Handle(GEOMImpl_Fillet1dDriver)((Handle(GEOMImpl_Fillet1dDriver)&)AnObject);
+ }
+ }
+
+ return _anOtherObject ;
+}
--- /dev/null
+// Copyright (C) 2009 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : GEOMImpl_Fillet1dDriver.ixx
+// Module : GEOMImpl
+
+#ifndef _GEOMImpl_Fillet1dDriver_HeaderFile
+#define _GEOMImpl_Fillet1dDriver_HeaderFile
+
+#ifndef _TColStd_SequenceOfExtendedString_HeaderFile
+#include <TColStd_SequenceOfExtendedString.hxx>
+#endif
+#ifndef _Standard_TypeMismatch_HeaderFile
+#include <Standard_TypeMismatch.hxx>
+#endif
+
+#ifndef _Standard_HeaderFile
+#include <Standard.hxx>
+#endif
+
+#ifndef _Standard_Macro_HeaderFile
+#include <Standard_Macro.hxx>
+#endif
+#ifndef _Standard_HeaderFile
+#include <Standard.hxx>
+#endif
+#ifndef _Standard_GUID_HeaderFile
+#include <Standard_GUID.hxx>
+#endif
+
+#ifndef _Handle_TFunction_Driver_HeaderFile
+#include <Handle_TFunction_Driver.hxx>
+#endif
+
+class Standard_Transient;
+class Handle_Standard_Type;
+class Handle(TFunction_Driver);
+class GEOMImpl_Fillet1dDriver;
+
+Standard_EXPORT Handle_Standard_Type& STANDARD_TYPE(GEOMImpl_Fillet1dDriver);
+
+class Handle(GEOMImpl_Fillet1dDriver) : public Handle(TFunction_Driver) {
+ public:
+ inline void* operator new(size_t,void* anAddress)
+ {
+ return anAddress;
+ }
+ inline void* operator new(size_t size)
+ {
+ return Standard::Allocate(size);
+ }
+ inline void operator delete(void *anAddress)
+ {
+ if (anAddress) Standard::Free((Standard_Address&)anAddress);
+ }
+
+ Handle(GEOMImpl_Fillet1dDriver)():Handle(TFunction_Driver)() {}
+ Handle(GEOMImpl_Fillet1dDriver)(const Handle(GEOMImpl_Fillet1dDriver)& aHandle) : Handle(TFunction_Driver)(aHandle)
+ {
+ }
+
+ Handle(GEOMImpl_Fillet1dDriver)(const GEOMImpl_Fillet1dDriver* anItem) : Handle(TFunction_Driver)((TFunction_Driver *)anItem)
+ {
+ }
+
+ Handle(GEOMImpl_Fillet1dDriver)& operator=(const Handle(GEOMImpl_Fillet1dDriver)& aHandle)
+ {
+ Assign(aHandle.Access());
+ return *this;
+ }
+
+ Handle(GEOMImpl_Fillet1dDriver)& operator=(const GEOMImpl_Fillet1dDriver* anItem)
+ {
+ Assign((Standard_Transient *)anItem);
+ return *this;
+ }
+
+ GEOMImpl_Fillet1dDriver* operator->()
+ {
+ return (GEOMImpl_Fillet1dDriver *)ControlAccess();
+ }
+
+ GEOMImpl_Fillet1dDriver* operator->() const
+ {
+ return (GEOMImpl_Fillet1dDriver *)ControlAccess();
+ }
+
+ Standard_EXPORT ~Handle(GEOMImpl_Fillet1dDriver)() {};
+
+ Standard_EXPORT static const Handle(GEOMImpl_Fillet1dDriver) DownCast(const Handle(Standard_Transient)& AnObject);
+};
+
+#ifndef _TFunction_Driver_HeaderFile
+#include <TFunction_Driver.hxx>
+#endif
+#ifndef _TFunction_Logbook_HeaderFile
+#include <TFunction_Logbook.hxx>
+#endif
+#ifndef _Standard_CString_HeaderFile
+#include <Standard_CString.hxx>
+#endif
+
+class TColStd_SequenceOfExtendedString;
+
+
+class GEOMImpl_Fillet1dDriver : public TFunction_Driver {
+
+public:
+
+ inline void* operator new(size_t,void* anAddress)
+ {
+ return anAddress;
+ }
+ inline void* operator new(size_t size)
+ {
+ return Standard::Allocate(size);
+ }
+ inline void operator delete(void *anAddress)
+ {
+ if (anAddress) Standard::Free((Standard_Address&)anAddress);
+ }
+
+ // Methods PUBLIC
+ //
+Standard_EXPORT GEOMImpl_Fillet1dDriver();
+Standard_EXPORT virtual Standard_Integer Execute(TFunction_Logbook& log) const;
+Standard_EXPORT virtual void Validate(TFunction_Logbook&) const {}
+Standard_EXPORT Standard_Boolean MustExecute(const TFunction_Logbook&) const { return Standard_True; }
+Standard_EXPORT static const Standard_GUID& GetID();
+Standard_EXPORT ~GEOMImpl_Fillet1dDriver() {};
+
+
+ // Type management
+ //
+Standard_EXPORT friend Handle_Standard_Type& GEOMImpl_Fillet1dDriver_Type_();
+Standard_EXPORT const Handle(Standard_Type)& DynamicType() const
+ { return STANDARD_TYPE(GEOMImpl_Fillet1dDriver) ; }
+Standard_EXPORT Standard_Boolean IsKind(const Handle(Standard_Type)& AType) const
+ { return (STANDARD_TYPE(GEOMImpl_Fillet1dDriver) == AType || TFunction_Driver::IsKind(AType)); }
+
+
+};
+
+#endif
#include <GEOMImpl_BooleanDriver.hxx>
#include <GEOMImpl_ChamferDriver.hxx>
#include <GEOMImpl_FilletDriver.hxx>
+#include <GEOMImpl_Fillet1dDriver.hxx>
#include <GEOMImpl_Fillet2dDriver.hxx>
#include <GEOMImpl_TranslateDriver.hxx>
#include <GEOMImpl_RotateDriver.hxx>
// Local Operations
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_ChamferDriver::GetID(), new GEOMImpl_ChamferDriver());
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_FilletDriver::GetID(), new GEOMImpl_FilletDriver());
+ TFunction_DriverTable::Get()->AddDriver(GEOMImpl_Fillet1dDriver::GetID(), new GEOMImpl_Fillet1dDriver());
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_Fillet2dDriver::GetID(), new GEOMImpl_Fillet2dDriver());
TFunction_DriverTable::Get()->AddDriver(GEOMImpl_ArchimedeDriver::GetID(), new GEOMImpl_ArchimedeDriver());
--- /dev/null
+// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+//NOTE: This is an interface to a function for the Fillet1d and creation.
+
+
+#include "GEOM_Function.hxx"
+
+#define FILLET1D_ARG_SH 1
+#define FILLET1D_ARG_R 2
+#define FILLET1D_ARG_LENG 3
+#define FILLET1D_ARG_LAST 4
+
+class GEOMImpl_IFillet1d
+{
+ public:
+
+ GEOMImpl_IFillet1d(Handle(GEOM_Function) theFunction): _func(theFunction) {}
+
+ void SetShape(Handle(GEOM_Function) theRef) { _func->SetReference(FILLET1D_ARG_SH, theRef); }
+ Handle(GEOM_Function) GetShape() { return _func->GetReference(FILLET1D_ARG_SH); }
+
+ void SetR(double theR) { _func->SetReal(FILLET1D_ARG_R, theR); }
+ void SetLength(int theLen) { _func->SetInteger(FILLET1D_ARG_LENG, theLen); }
+ void SetVertex(int theInd, int theVertex)
+ { _func->SetInteger(FILLET1D_ARG_LAST + theInd, theVertex); }
+
+ double GetR() { return _func->GetReal(FILLET1D_ARG_R); }
+ int GetLength() { return _func->GetInteger(FILLET1D_ARG_LENG); }
+ int GetVertex(int theInd) { return _func->GetInteger(FILLET1D_ARG_LAST + theInd); }
+
+ private:
+
+ Handle(GEOM_Function) _func;
+};
#include <GEOMImpl_Types.hxx>
#include <GEOMImpl_FilletDriver.hxx>
+#include <GEOMImpl_Fillet1dDriver.hxx>
#include <GEOMImpl_Fillet2dDriver.hxx>
#include <GEOMImpl_ChamferDriver.hxx>
#include <GEOMImpl_IFillet.hxx>
+#include <GEOMImpl_IFillet1d.hxx>
#include <GEOMImpl_IFillet2d.hxx>
#include <GEOMImpl_IChamfer.hxx>
return aFillet2D;
}
+//=============================================================================
+/*!
+ * MakeFillet1D
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_ILocalOperations::MakeFillet1D
+ (Handle(GEOM_Object) theShape, double theR, std::list<int> theVertexes)
+{
+ SetErrorCode(KO);
+
+ //Add a new Fillet object
+ Handle(GEOM_Object) aFillet1D = GetEngine()->AddObject(GetDocID(), GEOM_FILLET_1D);
+
+ //Add a new Fillet function
+ Handle(GEOM_Function) aFunction =
+ aFillet1D->AddFunction(GEOMImpl_Fillet1dDriver::GetID(), FILLET_1D_SHAPE_VERTEXES);
+ if (aFunction.IsNull()) return NULL;
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_Fillet1dDriver::GetID()) return NULL;
+
+ GEOMImpl_IFillet1d aCI (aFunction);
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return NULL;
+
+ aCI.SetShape(aRefShape);
+ aCI.SetR(theR);
+ int aLen = theVertexes.size();
+ aCI.SetLength(aLen);
+
+ int ind = 1;
+ std::list<int>::iterator it = theVertexes.begin();
+ for (; it != theVertexes.end(); it++, ind++) {
+ aCI.SetVertex(ind, (*it));
+ }
+
+ //Compute the Fillet value
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("1D Fillet driver failed");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return NULL;
+ }
+
+ //Make a Python command
+ GEOM::TPythonDump pd (aFunction);
+ pd << aFillet1D << " = geompy.MakeFillet1D(" << theShape
+ << ", " << theR << ", [";
+
+ it = theVertexes.begin();
+ pd << (*it++);
+ while (it != theVertexes.end()) {
+ pd << ", " << (*it++);
+ }
+ pd << "])";
+
+ SetErrorCode(OK);
+ return aFillet1D;
+}
+
//=============================================================================
/*!
* MakeChamferAll
std::list<int> theFaces);
Standard_EXPORT Handle(GEOM_Object) MakeFillet2D (Handle(GEOM_Object) theShape, double theR,
std::list<int> theVertexes);
+ Standard_EXPORT Handle(GEOM_Object) MakeFillet1D (Handle(GEOM_Object) theShape, double theR,
+ std::list<int> theVertexes);
Standard_EXPORT Handle(GEOM_Object) MakeChamferAll (Handle(GEOM_Object) theShape, double theD);
Standard_EXPORT Handle(GEOM_Object) MakeChamferEdge (Handle(GEOM_Object) theShape,
#define GEOM_FILLET 20
#define GEOM_FILLET_2D 45
+#define GEOM_FILLET_1D 46
#define GEOM_CHAMFER 21
#define GEOM_EDGE 22
#define FILLET_SHAPE_FACES_2R 5
#define FILLET_2D_SHAPE_VERTEXES 1
+#define FILLET_1D_SHAPE_VERTEXES 1
#define CHAMFER_SHAPE_ALL 1
#define CHAMFER_SHAPE_EDGE 2
GEOMImpl_ISpline.hxx \
GEOMImpl_IEllipse.hxx \
GEOMImpl_IFillet.hxx \
+ GEOMImpl_IFillet1d.hxx \
GEOMImpl_IFillet2d.hxx \
GEOMImpl_IChamfer.hxx \
GEOMImpl_ICopy.hxx \
GEOMImpl_SketcherDriver.hxx \
GEOMImpl_3DSketcherDriver.hxx \
GEOMImpl_FilletDriver.hxx \
+ GEOMImpl_Fillet1d.hxx \
+ GEOMImpl_Fillet1dDriver.hxx \
GEOMImpl_Fillet2dDriver.hxx \
GEOMImpl_ChamferDriver.hxx \
GEOMImpl_BooleanDriver.hxx \
GEOMImpl_SketcherDriver.cxx \
GEOMImpl_3DSketcherDriver.cxx \
GEOMImpl_FilletDriver.cxx \
+ GEOMImpl_Fillet1d.cxx \
+ GEOMImpl_Fillet1dDriver.cxx \
GEOMImpl_Fillet2dDriver.cxx \
GEOMImpl_ChamferDriver.cxx \
GEOMImpl_BooleanDriver.cxx \
return GetObject(anObject);
}
+//=============================================================================
+/*!
+ * MakeFillet1D
+ */
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_ILocalOperations_i::MakeFillet1D
+ (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR,
+ const GEOM::ListOfLong& theVertexes)
+{
+ GEOM::GEOM_Object_var aGEOMObject;
+
+ //Get the reference shape (wire)
+ Handle(GEOM_Object) aShapeRef = GetObjectImpl(theShape);
+ if (aShapeRef.IsNull()) return aGEOMObject._retn();
+
+ //Get the reference vertex
+ int ind = 0;
+ int aLen = theVertexes.length();
+ list<int> aVertexes;
+ for (; ind < aLen; ind++) {
+ aVertexes.push_back(theVertexes[ind]);
+ }
+
+ //Create the Fillet
+ Handle(GEOM_Object) anObject =
+ GetOperations()->MakeFillet1D(aShapeRef, theR, aVertexes);
+ if (!GetOperations()->IsDone() || anObject.IsNull())
+ return aGEOMObject._retn();
+
+ return GetObject(anObject);
+}
+
//=============================================================================
/*!
* MakeChamferAll
GEOM::GEOM_Object_ptr MakeFillet2D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR,
const GEOM::ListOfLong& theVertexes);
+ GEOM::GEOM_Object_ptr MakeFillet1D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR,
+ const GEOM::ListOfLong& theVertexes);
+
GEOM::GEOM_Object_ptr MakeChamferAll (GEOM::GEOM_Object_ptr theShape, CORBA::Double theD);
GEOM::GEOM_Object_ptr MakeChamferEdge (GEOM::GEOM_Object_ptr theShape,
return NULL;
}
+//=============================================================================
+// MakeFillet1D:
+//=============================================================================
+GEOM::GEOM_Object_ptr GEOM_Superv_i::MakeFillet1D (GEOM::GEOM_Object_ptr theShape,
+ CORBA::Double theR,
+ GEOM::GEOM_List_ptr theVertexes)
+{
+ beginService( " GEOM_Superv_i::MakeFillet1D" );
+ MESSAGE("GEOM_Superv_i::MakeFillet1D");
+ if (GEOM_List_i<GEOM::ListOfLong>* aListImplV =
+ dynamic_cast<GEOM_List_i<GEOM::ListOfLong>*>(GetServant(theVertexes, myPOA).in())) {
+ getLocalOp();
+ GEOM::GEOM_Object_ptr anObj = myLocalOp->MakeFillet1D(theShape, theR, aListImplV->GetList());
+ endService( " GEOM_Superv_i::MakeFillet1D" );
+ return anObj;
+ }
+ endService( " GEOM_Superv_i::MakeFillet1D" );
+ return NULL;
+}
+
//=============================================================================
// MakeChamferAll:
//=============================================================================
CORBA::Double theR2, GEOM::GEOM_List_ptr theFaces);
GEOM::GEOM_Object_ptr MakeFillet2D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR,
GEOM::GEOM_List_ptr theVertexes);
+ GEOM::GEOM_Object_ptr MakeFillet1D (GEOM::GEOM_Object_ptr theShape, CORBA::Double theR,
+ GEOM::GEOM_List_ptr theVertexes);
GEOM::GEOM_Object_ptr MakeChamferAll (GEOM::GEOM_Object_ptr theShape, CORBA::Double theD);
GEOM::GEOM_Object_ptr MakeChamferEdge (GEOM::GEOM_Object_ptr theShape,
CORBA::Double theD1, CORBA::Double theD2,
anObj.SetParameters(Parameters)
return anObj
+ ## Perform a fillet on the specified edges of the given wire shape
+ # @param theShape - Wire Shape(with planar edges) to perform fillet on.
+ # @param theR - Fillet radius.
+ # @param theListOfVertexes Global indices of vertexes to perform fillet on.
+ # \note Global index of sub-shape can be obtained, using method geompy.GetSubShapeID().
+ # @return New GEOM_Object, containing the result shape.
+ #
+ # @ref tui_fillet1d "Example"
+ def MakeFillet1D(self,theShape, theR, theListOfVertexes):
+ # Example: see GEOM_TestAll.py
+ anObj = self.LocalOp.MakeFillet1D(theShape, theR, theListOfVertexes)
+ RaiseIfFailed("MakeFillet1D", self.LocalOp)
+ return anObj
+
## Perform a fillet on the specified edges/faces of the given shape
# @param theShape - Face Shape to perform fillet on.
# @param theR - Fillet radius.
RaiseIfFailed("MakeFillet2D", self.LocalOp)
return anObj
+ ## Perform a fillet on the specified edges of the given shape
+ # @param theShape - Wire Shape to perform fillet on.
+ # @param theR - Fillet radius.
+ # @param theListOfVertexes Global indices of vertexes to perform fillet on.
+ # \note Global index of sub-shape can be obtained, using method geompy.GetSubShapeID().
+ # \note The list of vertices could be empty,
+ # in this case fillet will done done at all vertices in wire
+ # @return New GEOM_Object, containing the result shape.
+ #
+ # @ref tui_fillet2d "Example"
+ def MakeFillet1D(self,theShape, theR, theListOfVertexes):
+ # Example: see GEOM_TestAll.py
+ anObj = self.LocalOp.MakeFillet1D(theShape, theR, theListOfVertexes)
+ RaiseIfFailed("MakeFillet1D", self.LocalOp)
+ return anObj
+
## Perform a symmetric chamfer on all edges of the given shape.
# @param theShape Shape, to perform chamfer on.
# @param theD Chamfer size along each face.
OperationGUI_ArchimedeDlg.h \
OperationGUI_PartitionDlg.h \
OperationGUI_FilletDlg.h \
- OperationGUI_Fillet2dDlg.h \
+ OperationGUI_Fillet1d2dDlg.h \
OperationGUI_ChamferDlg.h \
OperationGUI_GetShapesOnShapeDlg.h \
OperationGUI_ClippingDlg.h
OperationGUI_PartitionDlg.cxx \
OperationGUI_GetShapesOnShapeDlg.cxx \
OperationGUI_FilletDlg.cxx \
- OperationGUI_Fillet2dDlg.cxx \
+ OperationGUI_Fillet1d2dDlg.cxx \
OperationGUI_ChamferDlg.cxx \
OperationGUI_ClippingDlg.cxx
OperationGUI_PartitionDlg_moc.cxx \
OperationGUI_GetShapesOnShapeDlg_moc.cxx\
OperationGUI_FilletDlg_moc.cxx \
- OperationGUI_Fillet2dDlg_moc.cxx \
+ OperationGUI_Fillet1d2dDlg_moc.cxx \
OperationGUI_ChamferDlg_moc.cxx \
OperationGUI_ClippingDlg_moc.cxx
#include "OperationGUI_PartitionDlg.h" // Method PARTITION
#include "OperationGUI_ArchimedeDlg.h" // Method ARCHIMEDE
#include "OperationGUI_FilletDlg.h" // Method FILLET
-#include "OperationGUI_Fillet2dDlg.h" // Method FILLET 2D
+#include "OperationGUI_Fillet1d2dDlg.h" // Method FILLET 2D and FILLET 1D
#include "OperationGUI_ChamferDlg.h" // Method CHAMFER
#include "OperationGUI_ClippingDlg.h" // Clipping dialog box
#include "OperationGUI_GetShapesOnShapeDlg.h"
case 506: ( new OperationGUI_ChamferDlg ( getGeometryGUI(), parent ) )->show(); break;
case 507: ( new OperationGUI_ClippingDlg ( getGeometryGUI(), parent ) )->show(); break;
case 508: ( new OperationGUI_GetShapesOnShapeDlg( getGeometryGUI(), parent ) )->show(); break;
- case 509: ( new OperationGUI_Fillet2dDlg ( getGeometryGUI(), parent ) )->show(); break;
+ case 510: ( new OperationGUI_Fillet1d2dDlg ( getGeometryGUI(), parent,true ) )->show(); break;
+ case 509: ( new OperationGUI_Fillet1d2dDlg ( getGeometryGUI(), parent,false ) )->show(); break;
default:
app->putInfo( tr( "GEOM_PRP_COMMAND" ).arg( theCommandID ) );
}
--- /dev/null
+// GEOM GEOMGUI : GUI for Geometry component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : OperationGUI_Fillet1d2dDlg.cxx
+// Author : DMV, OCN.
+//
+
+#include "OperationGUI_Fillet1d2dDlg.h"
+
+#include <DlgRef.h>
+#include <GeometryGUI.h>
+#include <GEOMBase.h>
+
+#include <SUIT_Desktop.h>
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_ViewWindow.h>
+#include <SUIT_ViewManager.h>
+#include <SalomeApp_Application.h>
+#include <LightApp_SelectionMgr.h>
+#include <OCCViewer_ViewModel.h>
+
+// OCCT Includes
+#include <TColStd_MapOfInteger.hxx>
+#include <TColStd_IndexedMapOfInteger.hxx>
+
+#include <GEOMImpl_Types.hxx>
+
+//=================================================================================
+// class : OperationGUI_Fillet1d2dDlg()
+// purpose : Constructs a OperationGUI_Fillet1d2dDlg which is a child of 'parent', with the
+// name 'name' and widget flags set to 'f'.
+// The dialog will by default be modeless, unless you set 'modal' to
+// TRUE to construct a modal dialog.
+//=================================================================================
+OperationGUI_Fillet1d2dDlg::OperationGUI_Fillet1d2dDlg (GeometryGUI* theGeometryGUI,
+ QWidget* parent,
+ bool is1D)
+ : GEOMBase_Skeleton(theGeometryGUI, parent, false),
+ myIs1D( is1D )
+{
+ SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
+ QPixmap image0 (aResMgr->loadPixmap("GEOM", myIs1D ? tr("ICON_DLG_FILLET_1D")
+ : tr("ICON_DLG_FILLET_2D")));
+ QPixmap iconSelect (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
+
+ setWindowTitle(myIs1D ? tr("GEOM_FILLET_1D_TITLE") : tr("GEOM_FILLET_2D_TITLE"));
+
+ /***************************************************************/
+ mainFrame()->GroupConstructors->setTitle(myIs1D ? tr("GEOM_FILLET_1D") : tr("GEOM_FILLET_2D"));
+ mainFrame()->RadioButton1->setIcon(image0);
+ mainFrame()->RadioButton2->close();
+ mainFrame()->RadioButton3->close();
+
+ GroupVertexes = new DlgRef_2Sel1Spin(centralWidget());
+ GroupVertexes->GroupBox1->setTitle(myIs1D ? tr("GEOM_FILLET_1D") : tr("GEOM_FILLET_2D"));
+ GroupVertexes->TextLabel1->setText(myIs1D ? tr("GEOM_PLANAR_EDGE_WIRE") : tr("GEOM_PLANAR_FACE"));
+ GroupVertexes->TextLabel2->setText(tr("GEOM_VERTEXES"));
+ GroupVertexes->TextLabel3->setText(tr("GEOM_RADIUS"));
+ GroupVertexes->PushButton1->setIcon(iconSelect);
+ GroupVertexes->PushButton2->setIcon(iconSelect);
+ GroupVertexes->LineEdit1->setReadOnly(true);
+ GroupVertexes->LineEdit2->setReadOnly(true);
+
+ QVBoxLayout* layout = new QVBoxLayout(centralWidget());
+ layout->setMargin(0); layout->setSpacing(6);
+ layout->addWidget(GroupVertexes);
+
+ /***************************************************************/
+
+ // Set range of spinboxes
+ double SpecificStep = 10.0;
+ initSpinBox(GroupVertexes->SpinBox_DX, 0.00001, COORD_MAX, SpecificStep, 5); // VSR: TODO: DBL_DIGITS_DISPLAY
+
+ setHelpFileName(myIs1D ? "fillet1d_operation_page.html" : "fillet2d_operation_page.html");
+
+ // Initialisation
+ Init();
+ resize(100,100);
+}
+
+//=================================================================================
+// function : ~OperationGUI_Fillet1d2dDlg()
+// purpose : Destroys the object and frees any allocated resources
+//=================================================================================
+OperationGUI_Fillet1d2dDlg::~OperationGUI_Fillet1d2dDlg()
+{
+}
+
+//=================================================================================
+// function : Init()
+// purpose :
+//=================================================================================
+void OperationGUI_Fillet1d2dDlg::Init()
+{
+ // Set Initial values of spinboxes
+ GroupVertexes->SpinBox_DX->setValue(5);
+
+ // Clear line edits
+ GroupVertexes->LineEdit1->setText("");
+ GroupVertexes->LineEdit2->setText("");
+
+ myShape = GEOM::GEOM_Object::_nil();
+
+ myVertexes.Clear();
+
+ // signals and slots connections
+
+ connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk() ));
+ connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
+
+ // connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
+
+ connect(GroupVertexes->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+ connect(GroupVertexes->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
+
+ connect(GroupVertexes->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
+ connect(GroupVertexes->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
+
+ connect(GroupVertexes->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
+
+ initName(myIs1D ? tr("GEOM_FILLET_1D") : tr("GEOM_FILLET_2D"));
+ GroupVertexes->PushButton1->click();
+}
+
+//=================================================================================
+// function : ClickOnOk()
+// purpose :
+//=================================================================================
+void OperationGUI_Fillet1d2dDlg::ClickOnOk()
+{
+ if (ClickOnApply())
+ ClickOnCancel();
+}
+
+//=================================================================================
+// function : ClickOnApply()
+// purpose :
+//=================================================================================
+bool OperationGUI_Fillet1d2dDlg::ClickOnApply()
+{
+ if (!onAccept())
+ return false;
+
+ initName();
+ // Reset dialog state
+ GroupVertexes->LineEdit1->setText("");
+ GroupVertexes->LineEdit2->setText("");
+ myShape = GEOM::GEOM_Object::_nil();
+ myVertexes.Clear();
+ GroupVertexes->PushButton1->click();
+
+ return true;
+}
+
+//=================================================================================
+// function : SelectionIntoArgument()
+// purpose : Called when selection is changed or on dialog initialization or activation
+//=================================================================================
+void OperationGUI_Fillet1d2dDlg::SelectionIntoArgument()
+{
+ erasePreview();
+ myEditCurrentArgument->setText("");
+
+ LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
+ SALOME_ListIO aSelList;
+ aSelMgr->selectedObjects(aSelList);
+
+ // If selection of main object is activated
+ if (myEditCurrentArgument == GroupVertexes->LineEdit1) {
+ myShape = GEOM::GEOM_Object::_nil();
+ if (aSelList.Extent() == 1) {
+ Standard_Boolean aResult = Standard_False;
+ GEOM::GEOM_Object_var anObj =
+ GEOMBase::ConvertIOinGEOMObject(aSelList.First(), aResult);
+
+ if (aResult && !anObj->_is_nil()) {
+ QString aName = GEOMBase::GetName( anObj );
+ TopoDS_Shape aShape;
+ if ( GEOMBase::GetShape( anObj, aShape, TopAbs_SHAPE ) && !aShape.IsNull() ) {
+ TColStd_IndexedMapOfInteger aMap;
+ aSelMgr->GetIndexes(aSelList.First(), aMap);
+ if ( aMap.Extent() == 1 ) { // Local Selection
+ int anIndex = aMap( 1 );
+ aName += QString( myIs1D ? ":wire_%1" : ":face_%1" ).arg( anIndex );
+
+ //Find SubShape Object in Father
+ GEOM::GEOM_Object_var aFindedObject = GEOMBase_Helper::findObjectInFather( anObj, aName );
+
+ if ( aFindedObject == GEOM::GEOM_Object::_nil() ) { // Object not found in study
+ GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
+ anObj = aShapesOp->GetSubShape( anObj, anIndex );
+ }
+ else
+ anObj = aFindedObject; // get Object from study
+ }
+ else { // Global Selection
+ if ( aShape.ShapeType() != (myIs1D ? TopAbs_WIRE : TopAbs_FACE) ) {
+ anObj = GEOM::GEOM_Object::_nil();
+ aName = "";
+ }
+ }
+ }
+ myShape = anObj;
+ myEditCurrentArgument->setText(aName
+);
+ displayPreview();
+ }
+ }
+ } else if (myEditCurrentArgument == GroupVertexes->LineEdit2) {
+ myVertexes.Clear();
+ bool isPreview = myIs1D;
+ if (aSelList.Extent() == 1) {
+ Standard_Boolean aResult = Standard_False;
+ GEOM::GEOM_Object_var anObj =
+ GEOMBase::ConvertIOinGEOMObject(aSelList.First(), aResult);
+
+ if (aResult && !anObj->_is_nil()) {
+ TColStd_IndexedMapOfInteger anIndexes;
+ aSelMgr->GetIndexes(aSelList.First(), anIndexes);
+
+ if (anIndexes.Extent() > 0) {
+ QString aName;
+ if (anIndexes.Extent() == 1) {
+ int anIndex = anIndexes(1);
+ aName = QString(GEOMBase::GetName(anObj)) + QString(":vertex_%1").arg(anIndex);
+ }
+ else
+ aName = tr("GEOM_MEN_POPUP_NAME").arg(anIndexes.Extent());
+
+ isPreview = true;
+ myEditCurrentArgument->setText(aName);
+ myVertexes = anIndexes;
+ }
+ }
+ }
+ if ( isPreview )
+ displayPreview();
+ }
+
+ if (myEditCurrentArgument == GroupVertexes->LineEdit1) {
+ if (!myShape->_is_nil() && myVertexes.Extent() == 0)
+ GroupVertexes->PushButton2->click();
+ }
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose :
+//=================================================================================
+void OperationGUI_Fillet1d2dDlg::SetEditCurrentArgument()
+{
+ QPushButton* send = (QPushButton*)sender();
+
+ if (send == GroupVertexes->PushButton1) {
+ myEditCurrentArgument = GroupVertexes->LineEdit1;
+ GroupVertexes->PushButton2->setDown(false);
+ GroupVertexes->LineEdit2->setEnabled(false);
+ }
+ else if (send == GroupVertexes->PushButton2) {
+ myEditCurrentArgument = GroupVertexes->LineEdit2;
+ GroupVertexes->PushButton1->setDown(false);
+ GroupVertexes->LineEdit1->setEnabled(false);
+ }
+
+ // enable line edit
+ myEditCurrentArgument->setEnabled(true);
+ myEditCurrentArgument->setFocus();
+ // after setFocus(), because it will be setDown(false) when loses focus
+ send->setDown(true);
+
+ activateSelection();
+
+ // seems we need it only to avoid preview disappearing, caused by selection mode change
+ displayPreview();
+}
+
+//=================================================================================
+// function : LineEditReturnPressed()
+// purpose :
+//=================================================================================
+void OperationGUI_Fillet1d2dDlg::LineEditReturnPressed()
+{
+ QLineEdit* send = (QLineEdit*)sender();
+
+ if (send == GroupVertexes->LineEdit1)
+ myEditCurrentArgument = GroupVertexes->LineEdit1;
+ else if (send == GroupVertexes->LineEdit2)
+ myEditCurrentArgument = GroupVertexes->LineEdit2;
+ else
+ return;
+
+ GEOMBase_Skeleton::LineEditReturnPressed();
+}
+
+//=================================================================================
+// function : ActivateThisDialog()
+// purpose :
+//=================================================================================
+void OperationGUI_Fillet1d2dDlg::ActivateThisDialog()
+{
+ GEOMBase_Skeleton::ActivateThisDialog();
+}
+
+//=================================================================================
+// function : enterEvent()
+// purpose :
+//=================================================================================
+void OperationGUI_Fillet1d2dDlg::enterEvent (QEvent*)
+{
+ if (!mainFrame()->GroupConstructors->isEnabled())
+ this->ActivateThisDialog();
+}
+
+//=================================================================================
+// function : ValueChangedInSpinBox()
+// purpose :
+//=================================================================================
+void OperationGUI_Fillet1d2dDlg::ValueChangedInSpinBox (double)
+{
+ displayPreview();
+}
+
+//=================================================================================
+// function : activateSelection
+// purpose : Activate selection in accordance with myEditCurrentArgument
+//=================================================================================
+void OperationGUI_Fillet1d2dDlg::activateSelection()
+{
+ disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
+ globalSelection();
+ if (myEditCurrentArgument == GroupVertexes->LineEdit1)
+ globalSelection( myIs1D ? GEOM_WIRE : GEOM_FACE ); // localSelection(myShape, myIs1D ? TopAbs_WIRE
+ // : TopAbs_FACE);
+ else if (!myShape->_is_nil() && myEditCurrentArgument == GroupVertexes->LineEdit2)
+ localSelection(myShape, TopAbs_VERTEX);
+
+ connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
+ this, SLOT(SelectionIntoArgument()));
+}
+
+//=================================================================================
+// function : createOperation
+// purpose :
+//=================================================================================
+GEOM::GEOM_IOperations_ptr OperationGUI_Fillet1d2dDlg::createOperation()
+{
+ return getGeomEngine()->GetILocalOperations(getStudyId());
+}
+
+//=================================================================================
+// function : isValid()
+// purpose : Verify validity of input data
+//=================================================================================
+bool OperationGUI_Fillet1d2dDlg::isValid (QString&)
+{
+ return !myShape->_is_nil() && (myIs1D || myVertexes.Extent() > 0);
+}
+
+//=================================================================================
+// function : execute
+// purpose :
+//=================================================================================
+bool OperationGUI_Fillet1d2dDlg::execute (ObjectList& objects)
+{
+ GEOM::GEOM_Object_var anObj;
+
+ GEOM::ListOfLong_var aListOfIndexes = new GEOM::ListOfLong;
+ aListOfIndexes->length(myVertexes.Extent());
+
+ for (int i = 1, n = myVertexes.Extent(); i <= n; i++)
+ aListOfIndexes[ i - 1 ] = myVertexes(i);
+
+ GEOM::GEOM_ILocalOperations_ptr op =
+ GEOM::GEOM_ILocalOperations::_narrow(getOperation());
+ anObj = (myIs1D ? op->MakeFillet1D(myShape, getRadius(), aListOfIndexes)
+ : op->MakeFillet2D(myShape, getRadius(), aListOfIndexes));
+
+ if (!anObj->_is_nil())
+ objects.push_back(anObj._retn());
+
+ return true;
+}
+
+//=================================================================================
+// function : getRadius
+// purpose : Get radius
+//=================================================================================
+double OperationGUI_Fillet1d2dDlg::getRadius() const
+{
+ return GroupVertexes ->SpinBox_DX->value();
+}
--- /dev/null
+// GEOM GEOMGUI : GUI for Geometry component
+//
+// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : OperationGUI_Fillet1d2dDlg.h
+// Author : DMV, OCN
+//
+
+#ifndef OPERATIONGUI_Fillet1d2dDLG_H
+#define OPERATIONGUI_Fillet1d2dDLG_H
+
+#include <GEOMBase_Skeleton.h>
+
+#include <TColStd_IndexedMapOfInteger.hxx>
+
+class DlgRef_2Sel1Spin;
+
+//=================================================================================
+// class : OperationGUI_Fillet1d2dDlg
+// purpose :
+//=================================================================================
+class OperationGUI_Fillet1d2dDlg : public GEOMBase_Skeleton
+{
+ Q_OBJECT
+
+public:
+ OperationGUI_Fillet1d2dDlg( GeometryGUI*, QWidget*, bool theIs1D );
+ ~OperationGUI_Fillet1d2dDlg();
+
+protected:
+ // redefined from GEOMBase_Helper
+ virtual GEOM::GEOM_IOperations_ptr createOperation();
+ virtual bool isValid( QString& );
+ virtual bool execute( ObjectList& );
+
+private slots:
+ void ClickOnOk();
+ bool ClickOnApply();
+ void ActivateThisDialog();
+ void LineEditReturnPressed();
+ void SelectionIntoArgument();
+ void SetEditCurrentArgument();
+ void ValueChangedInSpinBox( double );
+
+private:
+ void Init();
+ void enterEvent( QEvent* );
+ void activateSelection();
+ double getRadius() const;
+
+private:
+ bool myIs1D;
+ GEOM::GEOM_Object_var myShape;
+ TColStd_IndexedMapOfInteger myVertexes;
+
+ DlgRef_2Sel1Spin* GroupVertexes;
+};
+
+#endif // OPERATIONGUI_Fillet1d2dDLG_H
+++ /dev/null
-// GEOM GEOMGUI : GUI for Geometry component
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-// File : OperationGUI_Fillet2dDlg.cxx
-// Author : DMV, OCN.
-//
-
-#include "OperationGUI_Fillet2dDlg.h"
-
-#include <DlgRef.h>
-#include <GeometryGUI.h>
-#include <GEOMBase.h>
-
-#include <SUIT_Desktop.h>
-#include <SUIT_Session.h>
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_ViewWindow.h>
-#include <SUIT_ViewManager.h>
-#include <SalomeApp_Application.h>
-#include <LightApp_SelectionMgr.h>
-#include <OCCViewer_ViewModel.h>
-
-// OCCT Includes
-#include <TColStd_MapOfInteger.hxx>
-#include <TColStd_IndexedMapOfInteger.hxx>
-
-#include <GEOMImpl_Types.hxx>
-
-//=================================================================================
-// class : OperationGUI_Fillet2dDlg()
-// purpose : Constructs a OperationGUI_Fillet2dDlg which is a child of 'parent', with the
-// name 'name' and widget flags set to 'f'.
-// The dialog will by default be modeless, unless you set 'modal' to
-// TRUE to construct a modal dialog.
-//=================================================================================
-OperationGUI_Fillet2dDlg::OperationGUI_Fillet2dDlg (GeometryGUI* theGeometryGUI, QWidget* parent)
- : GEOMBase_Skeleton(theGeometryGUI, parent, false)
-{
- SUIT_ResourceMgr* aResMgr = myGeomGUI->getApp()->resourceMgr();
- QPixmap image0 (aResMgr->loadPixmap("GEOM", tr("ICON_DLG_FILLET_2D")));
- QPixmap iconSelect (aResMgr->loadPixmap("GEOM", tr("ICON_SELECT")));
-
- setWindowTitle(tr("GEOM_FILLET_2D_TITLE"));
-
- /***************************************************************/
- mainFrame()->GroupConstructors->setTitle(tr("GEOM_FILLET_2D"));
- mainFrame()->RadioButton1->setIcon(image0);
- mainFrame()->RadioButton2->close();
- mainFrame()->RadioButton3->close();
-
- GroupVertexes = new DlgRef_2Sel1Spin(centralWidget());
- GroupVertexes->GroupBox1->setTitle(tr("GEOM_FILLET_2D"));
- GroupVertexes->TextLabel1->setText(tr("GEOM_PLANAR_FACE"));
- GroupVertexes->TextLabel2->setText(tr("GEOM_VERTEXES"));
- GroupVertexes->TextLabel3->setText(tr("GEOM_RADIUS"));
- GroupVertexes->PushButton1->setIcon(iconSelect);
- GroupVertexes->PushButton2->setIcon(iconSelect);
- GroupVertexes->LineEdit1->setReadOnly(true);
- GroupVertexes->LineEdit2->setReadOnly(true);
-
- QVBoxLayout* layout = new QVBoxLayout(centralWidget());
- layout->setMargin(0); layout->setSpacing(6);
- layout->addWidget(GroupVertexes);
-
- /***************************************************************/
-
- // Set range of spinboxes
- double SpecificStep = 10.0;
- initSpinBox(GroupVertexes->SpinBox_DX, 0.00001, COORD_MAX, SpecificStep, 5); // VSR: TODO: DBL_DIGITS_DISPLAY
-
- setHelpFileName("fillet2d_operation_page.html");
-
- // Initialisation
- Init();
- resize(100,100);
-}
-
-//=================================================================================
-// function : ~OperationGUI_Fillet2dDlg()
-// purpose : Destroys the object and frees any allocated resources
-//=================================================================================
-OperationGUI_Fillet2dDlg::~OperationGUI_Fillet2dDlg()
-{
-}
-
-//=================================================================================
-// function : Init()
-// purpose :
-//=================================================================================
-void OperationGUI_Fillet2dDlg::Init()
-{
- // Set Initial values of spinboxes
- GroupVertexes->SpinBox_DX->setValue(5);
-
- // Clear line edits
- GroupVertexes->LineEdit1->setText("");
- GroupVertexes->LineEdit2->setText("");
-
- myShape = GEOM::GEOM_Object::_nil();
-
- myVertexes.Clear();
-
- // signals and slots connections
-
- connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk() ));
- connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
-
- // connect(this, SIGNAL(constructorsClicked(int)), this, SLOT(ConstructorsClicked(int)));
-
- connect(GroupVertexes->PushButton1, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
- connect(GroupVertexes->PushButton2, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
-
- connect(GroupVertexes->LineEdit1, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
- connect(GroupVertexes->LineEdit2, SIGNAL(returnPressed()), this, SLOT(LineEditReturnPressed()));
-
- connect(GroupVertexes->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double)));
-
- initName(tr("GEOM_FILLET_2D"));
- GroupVertexes->PushButton1->click();
-}
-
-//=================================================================================
-// function : ClickOnOk()
-// purpose :
-//=================================================================================
-void OperationGUI_Fillet2dDlg::ClickOnOk()
-{
- if (ClickOnApply())
- ClickOnCancel();
-}
-
-//=================================================================================
-// function : ClickOnApply()
-// purpose :
-//=================================================================================
-bool OperationGUI_Fillet2dDlg::ClickOnApply()
-{
- if (!onAccept())
- return false;
-
- initName();
- // Reset dialog state
- GroupVertexes->LineEdit1->setText("");
- GroupVertexes->LineEdit2->setText("");
- myShape = GEOM::GEOM_Object::_nil();
- myVertexes.Clear();
- GroupVertexes->PushButton1->click();
-
- return true;
-}
-
-//=================================================================================
-// function : SelectionIntoArgument()
-// purpose : Called when selection is changed or on dialog initialization or activation
-//=================================================================================
-void OperationGUI_Fillet2dDlg::SelectionIntoArgument()
-{
- erasePreview();
- myEditCurrentArgument->setText("");
-
- LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
- SALOME_ListIO aSelList;
- aSelMgr->selectedObjects(aSelList);
-
- // If selection of main object is activated
- if (myEditCurrentArgument == GroupVertexes->LineEdit1) {
- myShape = GEOM::GEOM_Object::_nil();
- if (aSelList.Extent() == 1) {
- Standard_Boolean aResult = Standard_False;
- GEOM::GEOM_Object_var anObj =
- GEOMBase::ConvertIOinGEOMObject(aSelList.First(), aResult);
-
- if (aResult && !anObj->_is_nil()) {
- QString aName = GEOMBase::GetName( anObj );
- TopoDS_Shape aShape;
- if ( GEOMBase::GetShape( anObj, aShape, TopAbs_SHAPE ) && !aShape.IsNull() ) {
- TColStd_IndexedMapOfInteger aMap;
- aSelMgr->GetIndexes(aSelList.First(), aMap);
- if ( aMap.Extent() == 1 ) { // Local Selection
- int anIndex = aMap( 1 );
- aName += QString( ":face_%1" ).arg( anIndex );
-
- //Find SubShape Object in Father
- GEOM::GEOM_Object_var aFindedObject = GEOMBase_Helper::findObjectInFather( anObj, aName );
-
- if ( aFindedObject == GEOM::GEOM_Object::_nil() ) { // Object not found in study
- GEOM::GEOM_IShapesOperations_var aShapesOp = getGeomEngine()->GetIShapesOperations( getStudyId() );
- anObj = aShapesOp->GetSubShape( anObj, anIndex );
- }
- else
- anObj = aFindedObject; // get Object from study
- }
- else { // Global Selection
- if ( aShape.ShapeType() != TopAbs_FACE ) {
- anObj = GEOM::GEOM_Object::_nil();
- aName = "";
- }
- }
- }
- myShape = anObj;
- myEditCurrentArgument->setText(aName
-);
- displayPreview();
- }
- }
- } else if (myEditCurrentArgument == GroupVertexes->LineEdit2) {
- myVertexes.Clear();
- if (aSelList.Extent() == 1) {
- Standard_Boolean aResult = Standard_False;
- GEOM::GEOM_Object_var anObj =
- GEOMBase::ConvertIOinGEOMObject(aSelList.First(), aResult);
-
- if (aResult && !anObj->_is_nil()) {
- TColStd_IndexedMapOfInteger anIndexes;
- aSelMgr->GetIndexes(aSelList.First(), anIndexes);
-
- if (anIndexes.Extent() > 0) {
- QString aName;
- if (anIndexes.Extent() == 1) {
- int anIndex = anIndexes(1);
- aName = QString(GEOMBase::GetName(anObj)) + QString(":vertex_%1").arg(anIndex);
- }
- else
- aName = tr("GEOM_MEN_POPUP_NAME").arg(anIndexes.Extent());
-
- myEditCurrentArgument->setText(aName);
- myVertexes = anIndexes;
- displayPreview();
- }
- }
- }
- }
-
- if (myEditCurrentArgument == GroupVertexes->LineEdit1) {
- if (!myShape->_is_nil() && myVertexes.Extent() == 0)
- GroupVertexes->PushButton2->click();
- }
-}
-
-//=================================================================================
-// function : SetEditCurrentArgument()
-// purpose :
-//=================================================================================
-void OperationGUI_Fillet2dDlg::SetEditCurrentArgument()
-{
- QPushButton* send = (QPushButton*)sender();
-
- if (send == GroupVertexes->PushButton1) {
- myEditCurrentArgument = GroupVertexes->LineEdit1;
- GroupVertexes->PushButton2->setDown(false);
- GroupVertexes->LineEdit2->setEnabled(false);
- }
- else if (send == GroupVertexes->PushButton2) {
- myEditCurrentArgument = GroupVertexes->LineEdit2;
- GroupVertexes->PushButton1->setDown(false);
- GroupVertexes->LineEdit1->setEnabled(false);
- }
-
- // enable line edit
- myEditCurrentArgument->setEnabled(true);
- myEditCurrentArgument->setFocus();
- // after setFocus(), because it will be setDown(false) when loses focus
- send->setDown(true);
-
- activateSelection();
-
- // seems we need it only to avoid preview disappearing, caused by selection mode change
- displayPreview();
-}
-
-//=================================================================================
-// function : LineEditReturnPressed()
-// purpose :
-//=================================================================================
-void OperationGUI_Fillet2dDlg::LineEditReturnPressed()
-{
- QLineEdit* send = (QLineEdit*)sender();
-
- if (send == GroupVertexes->LineEdit1)
- myEditCurrentArgument = GroupVertexes->LineEdit1;
- else if (send == GroupVertexes->LineEdit2)
- myEditCurrentArgument = GroupVertexes->LineEdit2;
- else
- return;
-
- GEOMBase_Skeleton::LineEditReturnPressed();
-}
-
-//=================================================================================
-// function : ActivateThisDialog()
-// purpose :
-//=================================================================================
-void OperationGUI_Fillet2dDlg::ActivateThisDialog()
-{
- GEOMBase_Skeleton::ActivateThisDialog();
-}
-
-//=================================================================================
-// function : enterEvent()
-// purpose :
-//=================================================================================
-void OperationGUI_Fillet2dDlg::enterEvent (QEvent*)
-{
- if (!mainFrame()->GroupConstructors->isEnabled())
- this->ActivateThisDialog();
-}
-
-//=================================================================================
-// function : ValueChangedInSpinBox()
-// purpose :
-//=================================================================================
-void OperationGUI_Fillet2dDlg::ValueChangedInSpinBox (double)
-{
- displayPreview();
-}
-
-//=================================================================================
-// function : activateSelection
-// purpose : Activate selection in accordance with myEditCurrentArgument
-//=================================================================================
-void OperationGUI_Fillet2dDlg::activateSelection()
-{
- disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
- globalSelection();
- if (myEditCurrentArgument == GroupVertexes->LineEdit1)
- globalSelection( GEOM_FACE ); // localSelection(myShape, TopAbs_FACE);
- else if (!myShape->_is_nil() && myEditCurrentArgument == GroupVertexes->LineEdit2)
- localSelection(myShape, TopAbs_VERTEX);
-
- connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
- this, SLOT(SelectionIntoArgument()));
-}
-
-//=================================================================================
-// function : createOperation
-// purpose :
-//=================================================================================
-GEOM::GEOM_IOperations_ptr OperationGUI_Fillet2dDlg::createOperation()
-{
- return getGeomEngine()->GetILocalOperations(getStudyId());
-}
-
-//=================================================================================
-// function : isValid()
-// purpose : Verify validity of input data
-//=================================================================================
-bool OperationGUI_Fillet2dDlg::isValid (QString&)
-{
- return !myShape->_is_nil() && myVertexes.Extent() > 0;
-}
-
-//=================================================================================
-// function : execute
-// purpose :
-//=================================================================================
-bool OperationGUI_Fillet2dDlg::execute (ObjectList& objects)
-{
- GEOM::GEOM_Object_var anObj;
-
- GEOM::ListOfLong_var aListOfIndexes = new GEOM::ListOfLong;
- aListOfIndexes->length(myVertexes.Extent());
-
- for (int i = 1, n = myVertexes.Extent(); i <= n; i++)
- aListOfIndexes[ i - 1 ] = myVertexes(i);
-
- anObj = GEOM::GEOM_ILocalOperations::_narrow(getOperation())->
- MakeFillet2D(myShape, getRadius(), aListOfIndexes);
-
- if (!anObj->_is_nil())
- objects.push_back(anObj._retn());
-
- return true;
-}
-
-//=================================================================================
-// function : getRadius
-// purpose : Get radius
-//=================================================================================
-double OperationGUI_Fillet2dDlg::getRadius() const
-{
- return GroupVertexes ->SpinBox_DX->value();
-}
+++ /dev/null
-// GEOM GEOMGUI : GUI for Geometry component
-//
-// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-//
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
-//
-// File : OperationGUI_Fillet2dDlg.h
-// Author : DMV, OCN
-//
-
-#ifndef OPERATIONGUI_FILLET2DDLG_H
-#define OPERATIONGUI_FILLET2DDLG_H
-
-#include <GEOMBase_Skeleton.h>
-
-#include <TColStd_IndexedMapOfInteger.hxx>
-
-class DlgRef_2Sel1Spin;
-
-//=================================================================================
-// class : OperationGUI_Fillet2dDlg
-// purpose :
-//=================================================================================
-class OperationGUI_Fillet2dDlg : public GEOMBase_Skeleton
-{
- Q_OBJECT
-
-public:
- OperationGUI_Fillet2dDlg( GeometryGUI*, QWidget* );
- ~OperationGUI_Fillet2dDlg();
-
-protected:
- // redefined from GEOMBase_Helper
- virtual GEOM::GEOM_IOperations_ptr createOperation();
- virtual bool isValid( QString& );
- virtual bool execute( ObjectList& );
-
-private slots:
- void ClickOnOk();
- bool ClickOnApply();
- void ActivateThisDialog();
- void LineEditReturnPressed();
- void SelectionIntoArgument();
- void SetEditCurrentArgument();
- void ValueChangedInSpinBox( double );
-
-private:
- void Init();
- void enterEvent( QEvent* );
- void activateSelection();
- double getRadius() const;
-
-private:
- GEOM::GEOM_Object_var myShape;
- TColStd_IndexedMapOfInteger myVertexes;
-
- DlgRef_2Sel1Spin* GroupVertexes;
-};
-
-#endif // OPERATIONGUI_FILLET2DDLG_H