#include "CurveCreator_Utils.hxx"
#include "CurveCreator.hxx"
+#include "CurveCreator_Curve.hxx"
#include "CurveCreator_UtilsICurve.hxx"
#include <GEOMUtils.hxx>
#include <Geom_Point.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_Line.hxx>
+#include <Geom_Curve.hxx>
+#include <Geom_TrimmedCurve.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
#include <SelectMgr_EntityOwner.hxx>
#include <SelectMgr_Selection.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepTools_WireExplorer.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <TColStd_HArray1OfBoolean.hxx>
+#include <TColStd_Array1OfReal.hxx>
#include <TColgp_Array1OfVec.hxx>
#include <GeomAPI_Interpolate.hxx>
const int SCENE_PIXEL_PROJECTION_TOLERANCE = 10;
const int SCENE_PIXEL_POINT_TOLERANCE = 5;
+#define PLN_FREE 0
+#define PLN_ORIGIN 1
+#define PLN_OX 2
+#define PLN_FIXED 3
+
+/**
+ * This static function returns the curve of original type from the edge.
+ *
+ * \param theEdge the edge
+ * \return the curve of original type. Can be null handle.
+ */
+static Handle(Geom_Curve) GetCurve(const TopoDS_Edge &theEdge)
+{
+ Handle(Geom_Curve) aResult;
+
+ if (theEdge.IsNull()) {
+ return aResult;
+ }
+
+ Standard_Real aF;
+ Standard_Real aL;
+
+ aResult = BRep_Tool::Curve(theEdge, aF, aL);
+
+ if (aResult.IsNull()) {
+ return aResult;
+ }
+
+ // Get the curve of original type
+ Handle(Standard_Type) aType = aResult->DynamicType();
+
+ while (aType == STANDARD_TYPE(Geom_TrimmedCurve)) {
+ Handle(Geom_TrimmedCurve) aTrCurve =
+ Handle(Geom_TrimmedCurve)::DownCast(aResult);
+
+ aResult = aTrCurve->BasisCurve();
+ aType = aResult->DynamicType();
+ }
+
+ return aResult;
+}
+
//=======================================================================
// function : ConvertClickToPoint()
// purpose : Returns the point clicked in 3D view
theShape = aComp;
}
+/**
+ * This is an intermediate structure for curve construction.
+ */
+struct Section3D
+{
+ Section3D() : myIsClosed(false), myIsBSpline(false)
+ { }
+
+ bool myIsClosed;
+ bool myIsBSpline;
+ Handle(TColgp_HArray1OfPnt) myPoints;
+};
+
+//=======================================================================
+// function : constructCurve
+// purpose :
+//=======================================================================
+bool CurveCreator_Utils::constructCurve
+ (const TopoDS_Shape theShape,
+ CurveCreator_Curve *theCurve,
+ gp_Ax3 &theLocalCS)
+{
+ if (theShape.IsNull()) {
+ return false;
+ }
+
+ // Collect wires or vertices from shape.
+ TopTools_ListOfShape aWOrV;
+ TopAbs_ShapeEnum aType = theShape.ShapeType();
+
+ if (aType == TopAbs_WIRE || aType == TopAbs_VERTEX) {
+ aWOrV.Append(theShape);
+ } else if (aType == TopAbs_COMPOUND) {
+ TopoDS_Iterator aShIter(theShape);
+
+ for (; aShIter.More(); aShIter.Next()) {
+ const TopoDS_Shape &aSubShape = aShIter.Value();
+
+ aType = aSubShape.ShapeType();
+
+ if (aType == TopAbs_WIRE || aType == TopAbs_VERTEX) {
+ aWOrV.Append(aSubShape);
+ } else {
+ // Only subshapes of types wire or vertex are supported.
+ return false;
+ }
+ }
+ } else {
+ // Only wire (vertex) or compound of wires (vertices) are supported.
+ return false;
+ }
+
+ // Treat each wire or vertex. Get points, compute the working plane.
+ gp_Pln aPlane;
+ Standard_Integer aPlaneStatus = PLN_FREE;
+ TopTools_ListIteratorOfListOfShape anIter(aWOrV);
+ std::list<Section3D> aListSec;
+
+ for (; anIter.More(); anIter.Next()) {
+ Section3D aSec3D;
+
+ aSec3D.myPoints = CurveCreator_Utils::getPoints
+ (anIter.Value(), aSec3D.myIsClosed, aSec3D.myIsBSpline);
+
+ if (aSec3D.myPoints.IsNull()) {
+ return false;
+ }
+
+ aListSec.push_back(aSec3D);
+
+ if (aPlaneStatus != PLN_FIXED) {
+ // Compute plane
+ CurveCreator_Utils::FindPlane(aSec3D.myPoints, aPlane, aPlaneStatus);
+ }
+ }
+
+ // Check if it is possible to change a computed coordinate system by
+ // XOY, XOZ or YOZ or parallel to them.
+ gp_Pnt aO(0., 0., 0.);
+ gp_Dir aNDir(0., 0., 1.);
+ gp_Dir aXDir(1., 0., 0.);
+ gp_Ax3 anAxis;
+ Standard_Real aTolAng = Precision::Confusion(); // Angular() is too small.
+
+ switch (aPlaneStatus) {
+ case PLN_ORIGIN:
+ {
+ // Change the location.
+ aO.SetZ(aPlane.Location().Z());
+ anAxis.SetLocation(aO);
+ aPlane.SetPosition(anAxis);
+ }
+ break;
+ case PLN_OX:
+ {
+ // Fixed origin + OX axis
+ const gp_Dir &aPlnX = aPlane.Position().XDirection();
+
+ if (Abs(aPlnX.Z()) <= aTolAng) {
+ // Make a coordinate system parallel to XOY.
+ aO.SetZ(aPlane.Location().Z());
+ anAxis.SetLocation(aO);
+ aPlane.SetPosition(anAxis);
+ } else if (Abs(aPlnX.Y()) <= aTolAng) {
+ // Make a coordinate system parallel to XOZ.
+ aO.SetY(aPlane.Location().Y());
+ aNDir.SetCoord(0., 1., 0.);
+ aXDir.SetCoord(0., 0., 1.);
+ anAxis = gp_Ax3(aO, aNDir, aXDir);
+ aPlane.SetPosition(anAxis);
+ } else if (Abs(aPlnX.X()) <= aTolAng) {
+ // Make a coordinate system parallel to YOZ.
+ aO.SetX(aPlane.Location().X());
+ aNDir.SetCoord(1., 0., 0.);
+ aXDir.SetCoord(0., 1., 0.);
+ anAxis = gp_Ax3(aO, aNDir, aXDir);
+ aPlane.SetPosition(anAxis);
+ }
+ }
+ break;
+ case PLN_FIXED:
+ {
+ const gp_Dir &aPlnN = aPlane.Position().Direction();
+ gp_Dir aYDir(0., 1., 0.);
+
+ if (aPlnN.IsParallel(aNDir, aTolAng)) {
+ // Make a coordinate system parallel to XOY.
+ aO.SetZ(aPlane.Location().Z());
+ anAxis.SetLocation(aO);
+ aPlane.SetPosition(anAxis);
+ } else if (aPlnN.IsParallel(aYDir, aTolAng)) {
+ // Make a coordinate system parallel to XOZ.
+ aO.SetY(aPlane.Location().Y());
+ aNDir.SetCoord(0., 1., 0.);
+ aXDir.SetCoord(0., 0., 1.);
+ anAxis = gp_Ax3(aO, aNDir, aXDir);
+ aPlane.SetPosition(anAxis);
+ } else if (aPlnN.IsParallel(aXDir, aTolAng)) {
+ // Make a coordinate system parallel to YOZ.
+ aO.SetX(aPlane.Location().X());
+ aNDir.SetCoord(1., 0., 0.);
+ aXDir.SetCoord(0., 1., 0.);
+ anAxis = gp_Ax3(aO, aNDir, aXDir);
+ aPlane.SetPosition(anAxis);
+ }
+ }
+ break;
+ case PLN_FREE:
+ default:
+ // Use XOY plane.
+ aPlane.SetPosition(anAxis);
+ break;
+ }
+
+ // Compute 2d points.
+ std::list<Section3D>::const_iterator aSecIt = aListSec.begin();
+ Standard_Real aTolConf2 =
+ Precision::Confusion()*Precision::Confusion();
+ Standard_Real aX;
+ Standard_Real aY;
+
+ for (; aSecIt != aListSec.end(); ++aSecIt) {
+ Standard_Integer i;
+ CurveCreator::Coordinates aCoords;
+
+ for (i = aSecIt->myPoints->Lower(); i <= aSecIt->myPoints->Upper(); ++i) {
+ const gp_Pnt &aPnt = aSecIt->myPoints->Value(i);
+
+ if (aPlane.SquareDistance(aPnt) > aTolConf2) {
+ // The point doesn't lie on the plane.
+ return false;
+ }
+
+ ElSLib::Parameters(aPlane, aPnt, aX, aY);
+ aCoords.push_back(aX);
+ aCoords.push_back(aY);
+ }
+
+ // Add a new section to the curve.
+ const std::string aSecName =
+ CurveCreator_UtilsICurve::getUniqSectionName(theCurve);
+ const CurveCreator::SectionType aSecType = aSecIt->myIsBSpline ?
+ CurveCreator::Spline : CurveCreator::Polyline;
+
+ theCurve->addSectionInternal(aSecName, aSecType,
+ aSecIt->myIsClosed, aCoords);
+ }
+
+ // Set the local coordinate system.
+ theLocalCS = aPlane.Position();
+
+ return true;
+}
+
class CompareSectionToPoint
{
public:
{
return theOtherPoint.IsEqual( thePoint, LOCAL_SELECTION_TOLERANCE );
}
+
+//=======================================================================
+// function : getPoints
+// purpose :
+//=======================================================================
+Handle(TColgp_HArray1OfPnt) CurveCreator_Utils::getPoints
+ (const TopoDS_Shape &theShape,
+ bool &IsClosed,
+ bool &IsBSpline)
+{
+ Handle(TColgp_HArray1OfPnt) aResult;
+
+ IsClosed = false;
+ IsBSpline = false;
+
+ if (theShape.IsNull()) {
+ return aResult;
+ }
+
+ const TopAbs_ShapeEnum aShType = theShape.ShapeType();
+
+ if (aShType == TopAbs_VERTEX) {
+ // There is a single point.
+ gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape));
+
+ aResult = new TColgp_HArray1OfPnt(1, 1, aPnt);
+
+ return aResult;
+ } else if (aShType != TopAbs_WIRE) {
+ // The shape is neither a vertex nor a wire.
+ return aResult;
+ }
+
+ // Treat wire.
+ BRepTools_WireExplorer anExp(TopoDS::Wire(theShape));
+
+ if (!anExp.More()) {
+ // Empty wires are not allowed.
+ return aResult;
+ }
+
+ // Treat the first edge.
+ TopoDS_Edge anEdge = anExp.Current();
+ Handle(Geom_Curve) aCurve = GetCurve(anEdge);
+
+ if (aCurve.IsNull()) {
+ return aResult;
+ }
+
+ // Check the curve type.
+ Handle(Standard_Type) aType = aCurve->DynamicType();
+
+ if (aType == STANDARD_TYPE(Geom_BSplineCurve)) {
+ IsBSpline = true;
+ } else if (aType != STANDARD_TYPE(Geom_Line)) {
+ // The curve is neither a line or a BSpline. It is not valid.
+ return aResult;
+ }
+
+ // Go to the next edge.
+ TopoDS_Vertex aFirstVtx = anExp.CurrentVertex();
+
+ anExp.Next();
+
+ if (IsBSpline) {
+ // There should be a single BSpline curve in the wire.
+ if (anExp.More()) {
+ return aResult;
+ }
+
+ // Construct a section from poles of BSpline.
+ Handle(Geom_BSplineCurve) aBSplCurve =
+ Handle(Geom_BSplineCurve)::DownCast(aCurve);
+
+ // Check if the edge is valid. It should not be based on trimmed curve.
+ gp_Pnt aCP[2] = { aBSplCurve->StartPoint(), aBSplCurve->EndPoint() };
+ TopoDS_Vertex aV[2];
+ Standard_Integer i;
+
+ TopExp::Vertices(anEdge, aV[0], aV[1]);
+
+ for (i = 0; i < 2; i++) {
+ gp_Pnt aPnt = BRep_Tool::Pnt(aV[i]);
+ Standard_Real aTol = BRep_Tool::Tolerance(aV[i]);
+
+ if (!aPnt.IsEqual(aCP[i], aTol)) {
+ return aResult;
+ }
+ }
+
+ IsClosed = aV[0].IsSame(aV[1]) ? true : false;
+
+ const Standard_Integer aNbPoints = aBSplCurve->NbKnots();
+ TColStd_Array1OfReal aKnots(1, aNbPoints);
+
+ aBSplCurve->Knots(aKnots);
+ aResult = new TColgp_HArray1OfPnt(1, aBSplCurve->NbKnots());
+
+ for (i = aKnots.Lower(); i <= aKnots.Upper(); ++i) {
+ aResult->SetValue(i, aBSplCurve->Value(aKnots.Value(i)));
+ }
+ } else {
+ // This is a polyline.
+ TopTools_ListOfShape aVertices;
+ Standard_Integer aNbVtx = 1;
+
+
+ aVertices.Append(aFirstVtx);
+
+ for (; anExp.More(); anExp.Next(), ++aNbVtx) {
+ anEdge = anExp.Current();
+ aCurve = GetCurve(anEdge);
+
+ if (aCurve.IsNull()) {
+ return aResult;
+ }
+
+ aType = aCurve->DynamicType();
+
+ if (aType != STANDARD_TYPE(Geom_Line)) {
+ // The curve is not a line. It is not valid.
+ return aResult;
+ }
+
+ // Add the current vertex to the list.
+ aVertices.Append(anExp.CurrentVertex());
+ }
+
+ // Check if the section is closed.
+ TopoDS_Vertex aLastVtx = TopExp::LastVertex(anEdge, Standard_True);
+
+ IsClosed = aFirstVtx.IsSame(aLastVtx) ? true : false;
+
+ // Fill the array of points.
+ aResult = new TColgp_HArray1OfPnt(1, aNbVtx);
+
+ Standard_Integer i;
+ TopTools_ListIteratorOfListOfShape aVtxIter(aVertices);
+
+ for (i = 1; aVtxIter.More(); aVtxIter.Next(), ++i) {
+ gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVtxIter.Value()));
+
+ aResult->SetValue(i, aPnt);
+ }
+ }
+
+ return aResult;
+}
+//=======================================================================
+// function : FindPlane
+// purpose :
+//=======================================================================
+void CurveCreator_Utils::FindPlane
+ (const Handle_TColgp_HArray1OfPnt &thePoints,
+ gp_Pln &thePlane,
+ Standard_Integer &thePlnStatus)
+{
+ if (thePoints.IsNull() || thePlnStatus == PLN_FIXED) {
+ // The plane can't be defined or is fixed. Nothing to change.
+ return;
+ }
+
+ Standard_Integer i;
+ const Standard_Real aTolConf = Precision::Confusion();
+
+ for (i = thePoints->Lower(); i <= thePoints->Upper(); ++i) {
+ const gp_Pnt &aPnt = thePoints->Value(i);
+
+ switch (thePlnStatus) {
+ case PLN_FREE:
+ // Fix the origin.
+ thePlane.SetLocation(aPnt);
+ thePlnStatus = PLN_ORIGIN;
+ break;
+ case PLN_ORIGIN:
+ {
+ // Fix origin + OX axis
+ const gp_Pnt &aPlnLoc = thePlane.Location();
+
+ if (!aPnt.IsEqual(aPlnLoc, aTolConf)) {
+ // Set the X axis.
+ gp_Dir aXDir(aPnt.XYZ().Subtracted(aPlnLoc.XYZ()));
+ gp_Ax3 aXNorm(aPlnLoc, aXDir);
+ gp_Ax3 aNewPlnPos(aPlnLoc, aXNorm.XDirection(), aXNorm.Direction());
+
+ thePlane.SetPosition(aNewPlnPos);
+ thePlnStatus = PLN_OX;
+ }
+ }
+ break;
+ case PLN_OX:
+ {
+ // Fix OY axis
+ gp_Lin aXLin(thePlane.XAxis());
+ Standard_Real aSqrDist = aXLin.SquareDistance(aPnt);
+
+ if (aSqrDist > aTolConf*aTolConf) {
+ // Compute main axis.
+ const gp_Pnt &aPlnLoc = thePlane.Location();
+ gp_Dir aDir(aPnt.XYZ().Subtracted(aPlnLoc.XYZ()));
+ gp_Ax3 aXNorm(aPlnLoc, aXLin.Direction(), aDir);
+ gp_Ax3 aNewPlnPos(aPlnLoc, aXNorm.YDirection(),
+ aXNorm.Direction());
+
+ thePlane.SetPosition(aNewPlnPos);
+ thePlnStatus = PLN_FIXED;
+ return;
+ }
+ }
+ break;
+ default:
+ return;
+ }
+ }
+}
#include <gp_Pnt.hxx>
#include <Geom_Curve.hxx>
#include <TopoDS_Shape.hxx>
+#include <TColgp_HArray1OfPnt.hxx>
#include <list>
#include <vector> // TODO: remove
+class CurveCreator_Curve;
+
class CurveCreator_Utils
{
CURVECREATOR_EXPORT static void constructShape( const CurveCreator_ICurve* theCurve,
TopoDS_Shape& theShape );
+ /**
+ * Generates a curve from a shape.
+ * \param theShape a shape to be converted to curve.
+ * \param theCurve a curve object to be initialized.
+ * \param theLocalCS the local coordinate system of the curve.
+ * \return true in case of success; false otherwise. Warning: the curve can
+ * be modified even if the shape is not valid for curve construction.
+ */
+ CURVECREATOR_EXPORT static bool constructCurve
+ (const TopoDS_Shape theShape,
+ CurveCreator_Curve *theCurve,
+ gp_Ax3 &theLocalCS);
+
/**
* Find selected points in the context
* \param theContext the viewer context
* \param theCurve a geometry curve
* \param theOutPoint a found projected point on the curve
*/
- CURVECREATOR_EXPORT static bool hasProjectPointOnCurve(
- Handle(V3d_View) theView,
- const int theX, const int theY,
- const Handle(Geom_Curve)& theCurve,
- Standard_Real& theParameter,
- int& theDelta );
+ static bool hasProjectPointOnCurve(
+ Handle(V3d_View) theView,
+ const int theX, const int theY,
+ const Handle(Geom_Curve)& theCurve,
+ Standard_Real& theParameter,
+ int& theDelta );
/*
* Returns whether the X and Y coordinates is in the pixel tolerance
* \param theDelta the sum of the a square of X and a square of Y
* \returns whether the points are provide to the pixel tolerance
*/
- CURVECREATOR_EXPORT static bool isEqualPixels( const int theX, const int theY,
- const int theOtherX, const int theOtherY,
- const double theTolerance, int& theDelta );
+ static bool isEqualPixels( const int theX, const int theY,
+ const int theOtherX, const int theOtherY,
+ const double theTolerance, int& theDelta );
/*
* \param theOtherPoint the second point
* \returns whether the points are provide to the pixel tolerance
*/
- CURVECREATOR_EXPORT static bool isEqualPoints( const gp_Pnt& thePoint,
- const gp_Pnt& theOtherPoint );
+ static bool isEqualPoints( const gp_Pnt& thePoint,
+ const gp_Pnt& theOtherPoint );
+
+ /**
+ * Returns the array of points of a shape to construct a curve section. The
+ * shape can be either a wire or a vertex. For vertex a single point in the
+ * array is returned.
+ *
+ * \param theShape the shape. Can be either a wire or a vertex.
+ * \param IsClosed closed flag. Output parameter.
+ * \param IsBSpline BSpline flag. Output parameter.
+ * \return the array of points. Null handle in case of failure.
+ */
+ static Handle_TColgp_HArray1OfPnt getPoints
+ (const TopoDS_Shape &theShape,
+ bool &IsClosed,
+ bool &IsBSpline);
+
+ /**
+ * This method computes a plane using the input points. The plane is defined
+ * by gp_Pln object and the status. The status can have one of the following
+ * values:
+ * - 0 plane is not set.<BR>
+ * - 1 origin of the plane is fixed. The plane is defined by 1 or several
+ * coincident points.<BR>
+ * - 2 origin + OX axis of the plane is fixed. The plane is defined by 2
+ * or more points that lie on a particular line.<BR>
+ * - 3 plane is fixed. Plane is defined by 3 not coincident points.<BR>
+ *
+ * \param thePoints the points.
+ * \param thePlane the current plane on input. It can be modified on output.
+ * \param thePlnStatus the current status on input. It can be modified on
+ * output.
+ */
+ static void FindPlane(const Handle_TColgp_HArray1OfPnt &thePoints,
+ gp_Pln &thePlane,
+ Standard_Integer &thePlnStatus);
+
};
#endif // CURVECREATOR_UTILS_H
#include <SUIT_ResourceMgr.h>
#include <SUIT_ViewManager.h>
-#include <OCCViewer_ViewWindow.h>
#include <OCCViewer_ViewManager.h>
#include <OCCViewer_ViewPort3d.h>
#include <OCCViewer_Utilities.h>
int theLocalPointRowLimit )
: QWidget(parent), myNewSectionEditor(NULL), myCurve(theCurve), mySection(0),
myDragStarted( false ), myDragInteractionStyle( SUIT_ViewModel::STANDARD ),
- myOCCViewer( 0 ), myLocalPointRowLimit( theLocalPointRowLimit )
+ myOCCViewer( 0 ), myLocalPointRowLimit( theLocalPointRowLimit ),
+ myOld2DMode(OCCViewer_ViewWindow::No2dMode)
{
bool isToEnableClosed = !( theActionFlags & DisableClosedSection );
myNewSectionEditor = new CurveCreator_NewSectionDlg( this, isToEnableClosed );
disconnect( aViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
// restore normal mode in the viewer
- OCCViewer_Utilities::setViewer2DMode( myOCCViewer, OCCViewer_ViewWindow::No2dMode );
+ SetViewer2DMode(false);
// all local contexts should be closed if the viewer is not more used
setLocalPointContext( false, true );
}
this, SLOT( onMouseMove( SUIT_ViewWindow*, QMouseEvent* ) ) );
connect( aViewManager, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
this, SLOT( onLastViewClosed( SUIT_ViewManager* ) ) );
- OCCViewer_Utilities::setViewer2DMode( myOCCViewer, OCCViewer_ViewWindow::XYPlane );
+ SetViewer2DMode(true);
}
}
return aMode;
}
+void CurveCreator_Widget::SetViewer2DMode(const bool To2D)
+{
+ if (myOCCViewer) {
+ if (To2D) {
+ myOld2DMode = OCCViewer_Utilities::setViewer2DMode
+ (myOCCViewer, OCCViewer_ViewWindow::XYPlane);
+ } else {
+ OCCViewer_Utilities::setViewer2DMode(myOCCViewer, myOld2DMode);
+ }
+ }
+}
+
//=================================================================================
// function : GeometryGUI::addCoordsByClick()
// purpose : Manage mouse press events in Additon mode
#include <QWidget>
#include <QMap>
+#include <OCCViewer_ViewWindow.h>
#include <SUIT_ViewWindow.h>
#include <AIS_InteractiveObject.hxx>
#include <AIS_InteractiveContext.hxx>
void setActionMode( const ActionMode& theMode );
ActionMode getActionMode() const;
+ void SetViewer2DMode(const bool To2D);
+
signals:
void selectionChanged();
void subOperationStarted( QWidget*, bool );
QByteArray myGuiState;
int myPressedX;
int myPressedY;
+ OCCViewer_ViewWindow::Mode2dType myOld2DMode;
};
#endif // CURVECREATOR_WIDGET_H
#include "EntityGUI_PolylineDlg.h"
#include <CurveCreator_Curve.hxx>
+#include <CurveCreator_Utils.hxx>
#include <CurveCreator_Widget.h>
#include <DlgRef.h>
#include <GeometryGUI.h>
+#include <GEOMBase.h>
#include <OCCViewer_ViewManager.h>
+#include <LightApp_SelectionMgr.h>
#include <SalomeApp_Application.h>
#include <SUIT_ResourceMgr.h>
#include <SUIT_Session.h>
+#include <BRep_Tool.hxx>
+#include <Geom_Surface.hxx>
+#include <GeomLib_IsPlanarSurface.hxx>
+#include <TopoDS.hxx>
+
#include <QGroupBox>
#include <QVBoxLayout>
+//#define SET_PLANE
//=================================================================================
// function : Constructor
//=================================================================================
EntityGUI_PolylineDlg::EntityGUI_PolylineDlg
(GeometryGUI* theGeometryGUI, QWidget* parent, bool modal, Qt::WindowFlags fl)
- : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl )
+ : GEOMBase_Skeleton( theGeometryGUI, parent, modal, fl ),
+ myCurve (0),
+ myEditorWidget (0),
+ myAddElementBox (0),
+ myPlnComboBox (0),
+ myPlnButton (0),
+ myPlnSelButton (0),
+ myWPlaneLineEdit (0),
+ myPolylineSelButton (0),
+ myPolylineEdit (0),
+ myEditCurrentArgument (0)
{
- QPixmap image0( SUIT_Session::session()->resourceMgr()->loadPixmap( "GEOM", tr( "ICON_CC_POLYLINE" ) ) );
+ QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_CC_POLYLINE")));
+ QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
setWindowTitle(tr("POLYLINE_DLG_TITLE"));
mainFrame()->RadioButton3->setAttribute( Qt::WA_DeleteOnClose );
mainFrame()->RadioButton3->close();
+ QGroupBox *aGroupBox1 = new QGroupBox(tr("GEOM_CS"), this);
+ QGridLayout *aPlaneLayout = new QGridLayout(aGroupBox1);
+
+ aPlaneLayout->setSpacing(6);
+ aPlaneLayout->setMargin(11);
+
+ myPlnComboBox = new QComboBox(aGroupBox1);
+ aPlaneLayout->addWidget(myPlnComboBox, 0, 0, 1, 3);
+
+ myPlnButton = new QPushButton (aGroupBox1);
+ myPlnButton->setText( tr( "GEOM_SKETCHER_RESTORE" ) );
+ aPlaneLayout->addWidget(myPlnButton, 0, 3);
+
+#ifdef SET_PLANE
+ QLabel *aPlaneLbl = new QLabel(tr("GEOM_PLANE"), aGroupBox1);
+
+ myPlnSelButton = new QPushButton (aGroupBox1);
+ myPlnSelButton->setIcon(image1);
+ myWPlaneLineEdit = new QLineEdit (aGroupBox1);
+ myWPlaneLineEdit->setReadOnly(true);
+#endif
+
+ QLabel *aPolylineLbl = new QLabel(tr("POLYLINE_IMPORT"), aGroupBox1);
+
+ myPolylineSelButton = new QPushButton (aGroupBox1);
+ myPolylineSelButton->setIcon(image1);
+ myPolylineEdit = new QLineEdit (aGroupBox1);
+ myPolylineEdit->setReadOnly(true);
+
+#ifdef SET_PLANE
+ aPlaneLayout->addWidget(aPlaneLbl, 1, 0);
+ aPlaneLayout->addWidget(myPlnSelButton, 1, 1);
+ aPlaneLayout->addWidget(myWPlaneLineEdit, 1, 2, 1, 2);
+#endif
+ aPlaneLayout->addWidget(aPolylineLbl, 2, 0);
+ aPlaneLayout->addWidget(myPolylineSelButton, 2, 1);
+ aPlaneLayout->addWidget(myPolylineEdit, 2, 2, 1, 2);
+
+ aPlaneLayout->setColumnStretch(2, 1);
+
myCurve = new CurveCreator_Curve( CurveCreator::Dim2d );
myEditorWidget = new CurveCreator_Widget (centralWidget(), myCurve);
myAddElementBox = new QGroupBox (tr("POLYLINE_ADD_SECTION"), centralWidget());
layout->setMargin( 0 );
layout->setSpacing( 6 );
+ layout->addWidget( aGroupBox1 );
layout->addWidget( myEditorWidget );
layout->addWidget( myAddElementBox );
SalomeApp_Application *anApp = myGeomGUI->getApp();
OCCViewer_ViewManager *aViewManager = dynamic_cast<OCCViewer_ViewManager*>
(anApp->getViewManager(OCCViewer_Viewer::Type(), true));
-
- myEditorWidget->setOCCViewer( aViewManager ? aViewManager->getOCCViewer() : 0 );
-
+ LightApp_SelectionMgr *aSelMgr = myGeomGUI->getApp()->selectionMgr();
+
+ myEditorWidget->setOCCViewer(aViewManager ? aViewManager->getOCCViewer() : 0);
+
+ // Init the list of local coordinate system
+ gp_Pnt aPnt(0., 0., 0.);
+ gp_Dir aDirN(0., 0., 1.);
+ gp_Dir aDirX(1., 0., 0.);
+ gp_Ax3 aLCS(aPnt, aDirN, aDirX);
+
+ //add Global CS
+ myPlnComboBox->addItem(tr("GEOM_GCS"), false);
+ myWPlaneList.push_back(GEOM::GeomObjPtr());
+ myLCSList.push_back(aLCS);
+
+ connect(myGeomGUI, SIGNAL(SignalDeactivateActiveDialog()), this, SLOT(DeactivateActiveDialog()));
+ connect(myGeomGUI, SIGNAL(SignalCloseAllDialogs()), this, SLOT(ClickOnCancel()));
+
+#ifdef SET_PLANE
+ connect(myPlnSelButton, SIGNAL(clicked()),
+ this, SLOT(SetEditCurrentArgument()));
+#endif
+ connect(myPolylineSelButton, SIGNAL(clicked()),
+ this, SLOT(SetEditCurrentArgument()));
+ connect(aSelMgr, SIGNAL(currentSelectionChanged()),
+ this, SLOT(SelectionIntoArgument()));
connect(myEditorWidget, SIGNAL(subOperationStarted(QWidget*, bool)),
this, SLOT(processStartedSubOperation(QWidget*, bool)));
connect(myEditorWidget, SIGNAL(subOperationFinished(QWidget*)),
this, SLOT(processFinishedSubOperation(QWidget*)));
connect(myEditorWidget, SIGNAL(curveModified()),
this, SLOT(onUpdatePreview()));
+#ifdef SET_PLANE
+ connect(myPlnComboBox, SIGNAL(activated(int)),
+ this, SLOT(ActivateLocalCS()));
+ connect(myPlnButton, SIGNAL(clicked()),
+ this, SLOT(ActivateLocalCS()));
+#endif
connect(buttonOk(), SIGNAL(clicked()), this, SLOT(ClickOnOk()));
connect(buttonApply(), SIGNAL(clicked()), this, SLOT(ClickOnApply()));
myAddElementBox->hide();
-
+ myPolylineSelButton->click();
SelectionIntoArgument();
}
}
//=================================================================================
-// function : createOperation
+// function : GetCurveParams
// purpose :
//=================================================================================
void EntityGUI_PolylineDlg::GetCurveParams(GEOM::ListOfListOfDouble &theCoords,
GetCurveParams(aCoords, aNames, aTypes, aCloseds);
- // Temporary code: get Working Plane.
- GEOM::GEOM_IBasicOperations_var aBasicOp = getGeomEngine()->GetIBasicOperations( getStudyId() );
- GEOM::GEOM_Object_var aWPlane = aBasicOp->MakeMarker( 0,0,0,
- 1,0,0,
- 0,1,0 );
-
- // Perform operation
- GEOM::GEOM_Object_var anObj = anOper->MakePolyline2DOnPlane
- (aCoords, aNames, aTypes, aCloseds, aWPlane);
+ // Get Working Plane.
+ int ind = myPlnComboBox->currentIndex();
+
+ if (ind != -1) {
+ bool isPlane = myPlnComboBox->itemData(ind).toBool();
+ GEOM::GEOM_Object_var anObj;
+
+ // Perform operation
+ if (isPlane) {
+ anObj = anOper->MakePolyline2DOnPlane
+ (aCoords, aNames, aTypes, aCloseds, myWPlaneList.at(ind).get());
+ } else {
+ gp_Ax3 anAxis = myLCSList.at(ind);
+ GEOM::ListOfDouble aPlane;
+
+ aPlane.length(9);
+ aPlane[0] = anAxis.Location().X();
+ aPlane[1] = anAxis.Location().Y();
+ aPlane[2] = anAxis.Location().Z();
+ aPlane[3] = anAxis.Direction().X();
+ aPlane[4] = anAxis.Direction().Y();
+ aPlane[5] = anAxis.Direction().Z();
+ aPlane[6] = anAxis.XDirection().X();
+ aPlane[7] = anAxis.XDirection().Y();
+ aPlane[8] = anAxis.XDirection().Z();
+
+ anObj = anOper->MakePolyline2D
+ (aCoords, aNames, aTypes, aCloseds, aPlane);
+ }
- if (!anObj->_is_nil()) {
- objects.push_back(anObj._retn());
+ if (!anObj->_is_nil()) {
+ objects.push_back(anObj._retn());
+ }
}
return true;
return true;
}
+//=================================================================================
+// function : ClickOnCancel()
+// purpose :
+//=================================================================================
+void EntityGUI_PolylineDlg::ClickOnCancel()
+{
+ myEditorWidget->SetViewer2DMode(false);
+ GEOMBase_Skeleton::ClickOnCancel();
+}
+
//=================================================================================
// function : processStartedSubOperation
// purpose :
}
//=================================================================================
-// function : execute
+// function : deleteSelected
// purpose : Redirect the delete action to editor widget
//=================================================================================
void EntityGUI_PolylineDlg::deleteSelected()
//=================================================================================
void EntityGUI_PolylineDlg::SelectionIntoArgument()
{
-/*
- GEOM::GeomObjPtr aSelectedObject = getSelected( TopAbs_SHAPE );
- TopoDS_Shape aShape;
-
- if ( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aShape ) && !aShape.IsNull() ) {
- if (aShape.ShapeType() == TopAbs_FACE) {
- QString aName = GEOMBase::GetName( aSelectedObject.get() );
- myGroup->LineEdit1->setText( aName );
-
- // clear selection
- disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
- myGeomGUI->getApp()->selectionMgr()->clearSelected();
- connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
- this, SLOT(SelectionIntoArgument()));
-
- myFace = aSelectedObject;
+ bool isModified = false;
+ GEOM::GeomObjPtr aSelectedObject = getSelected(TopAbs_SHAPE);
+ TopoDS_Shape aShape;
+
+ if (aSelectedObject && GEOMBase::GetShape(aSelectedObject.get(), aShape) &&
+ !aShape.IsNull()) {
+ QString aName = GEOMBase::GetName(aSelectedObject.get());
+
+ if (myEditCurrentArgument == myPolylineEdit) {
+ // Import a curve
+ CurveCreator_Curve *aNewCurve =
+ new CurveCreator_Curve(CurveCreator::Dim2d);
+ gp_Ax3 aLocalCS;
+
+ if (CurveCreator_Utils::constructCurve(aShape, aNewCurve, aLocalCS)) {
+ // Change the current curve be the new one.
+ myEditorWidget->setCurve(aNewCurve);
+ delete myCurve;
+ myCurve = aNewCurve;
+ isModified = true;
+ myPolylineEdit->setText(aName);
+#ifdef SET_PLANE
+ AddLocalCS(aSelectedObject.get(), false, aLocalCS);
+ myWPlaneLineEdit->clear();
+ myPlnSelButton->setDown(false);
+#endif
+ myPolylineSelButton->setDown(true);
+ } else {
+ // Does nothing, just clears selection.
+ delete aNewCurve;
+ }
+#ifdef SET_PLANE
+ } else if (myEditCurrentArgument == myWPlaneLineEdit) {
+ // Import planar face.
+ if (aShape.ShapeType() == TopAbs_FACE) {
+ // Check if the face is planar
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape));
+ GeomLib_IsPlanarSurface aPlanarCheck(aSurf, Precision::Confusion());
+
+ if (aPlanarCheck.IsPlanar()) {
+ myWPlaneLineEdit->setText(aName);
+ myPolylineEdit->clear();
+ AddLocalCS(aSelectedObject.get(), true,
+ WPlaneToLCS(aSelectedObject.get()));
+ isModified = true;
+ myPlnSelButton->setDown(true);
+ myPolylineSelButton->setDown(false);
+ }
+ }
+
+ if (!isModified) {
+ myEditCurrentArgument->setText(tr("GEOM_SKETCHER_WPLANE"));
+ }
+#endif
}
}
- displayPreview(true);
-*/
+ if (!isModified) {
+ // Does nothing, just clears selection.
+ disconnect(myGeomGUI->getApp()->selectionMgr(), 0, this, 0);
+ myGeomGUI->getApp()->selectionMgr()->clearSelected();
+ connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
+ this, SLOT(SelectionIntoArgument()));
+ }
+}
+
+//=================================================================================
+// function : SetEditCurrentArgument()
+// purpose :
+//=================================================================================
+void EntityGUI_PolylineDlg::SetEditCurrentArgument()
+{
+ if (sender() == myPlnSelButton) {
+#ifdef SET_PLANE
+ myEditCurrentArgument = myWPlaneLineEdit;
+ myEditCurrentArgument->setFocus();
+ myPlnSelButton->setDown(true);
+ myPolylineSelButton->setDown(false);
+#endif
+ } else if (sender() == myPolylineSelButton) {
+ myEditCurrentArgument = myPolylineEdit;
+ myEditCurrentArgument->setFocus();
+#ifdef SET_PLANE
+ myPlnSelButton->setDown(false);
+#endif
+ myPolylineSelButton->setDown(true);
+ }
}
//=================================================================================
{
GEOMBase_Skeleton::ActivateThisDialog();
- SelectionIntoArgument();
+ connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()),
+ this, SLOT(SelectionIntoArgument()));
}
//=================================================================================
{
displayPreview(true);
}
+
+//=================================================================================
+// function : ActivateLocalCS
+// purpose : Activate & Fit Working plane
+//=================================================================================
+void EntityGUI_PolylineDlg::ActivateLocalCS()
+{
+ const int ind = myPlnComboBox->currentIndex();
+
+ if (ind == 0) {
+ // Default plane
+#ifdef SET_PLANE
+ myWPlaneLineEdit->clear();
+#endif
+ myPolylineEdit->clear();
+ } else if (ind > 0) { // Skip 0 as it is default
+ // Update text on line edits.
+ QString aName = GEOMBase::GetName(GetActiveWPlane().get());
+ bool isPlane = myPlnComboBox->itemData(ind).toBool();
+
+ if (isPlane) {
+#ifdef SET_PLANE
+ myWPlaneLineEdit->setText(aName);
+#endif
+ myPolylineEdit->clear();
+ } else {
+ myPolylineEdit->setText(aName);
+#ifdef SET_PLANE
+ myWPlaneLineEdit->clear();
+#endif
+ }
+ }
+
+ gp_Ax3 anAxis = GetActiveLocalCS();
+
+ myGeomGUI->SetWorkingPlane(anAxis);
+ myGeomGUI->ActiveWorkingPlane();
+}
+
+//=================================================================================
+// function : GetActiveLocalCS
+// purpose : Get Working plane
+//=================================================================================
+gp_Ax3 EntityGUI_PolylineDlg::GetActiveLocalCS()
+{
+ const int ind = myPlnComboBox->currentIndex();
+
+ return ind >= 0 ? myLCSList.at(ind) : myGeomGUI->GetWorkingPlane();
+}
+
+//=================================================================================
+// function : GetActiveWPlane
+// purpose : Get Working plane
+//=================================================================================
+GEOM::GeomObjPtr EntityGUI_PolylineDlg::GetActiveWPlane()
+{
+ const int ind = myPlnComboBox->currentIndex();
+
+ return ind >= 0 ? myWPlaneList.at(ind) : GEOM::GeomObjPtr();
+}
+
+//=================================================================================
+// function : AddLocalCS()
+// purpose : Add All Coordinates systems in study
+//=================================================================================
+void EntityGUI_PolylineDlg::AddLocalCS(GEOM::GeomObjPtr theSelectedObject,
+ const bool IsPlane,
+ const gp_Ax3 &theLCS)
+{
+ QString aName = GEOMBase::GetName(theSelectedObject.get());
+
+ int index = myPlnComboBox->findText(aName, Qt::MatchExactly);
+
+ if (index == -1) { // If the working plane hasn't been added yet
+ myWPlaneList.push_back(theSelectedObject);
+ myLCSList.push_back(theLCS);
+ myPlnComboBox->addItem(aName, QVariant(IsPlane));
+ index = myPlnComboBox->count();
+ myPlnComboBox->setCurrentIndex(index - 1);
+ } else {
+ myPlnComboBox->setCurrentIndex(index);
+ }
+ ActivateLocalCS();
+}
+
+//=================================================================================
+// function : WPlaneToLCS ( aWPlane )
+// purpose :
+//=================================================================================
+gp_Ax3 EntityGUI_PolylineDlg::WPlaneToLCS(GEOM::GeomObjPtr theGeomObj)
+{
+ TopoDS_Shape aShape =
+ GEOM_Client::get_client().GetShape(GeometryGUI::GetGeomGen(), theGeomObj.get());
+ gp_Ax3 aLCS;
+
+ if (theGeomObj || aShape.IsNull()) {
+ MESSAGE("CORBA::is_nil(theGeomObj) || aShape.IsNull()")
+ }
+
+ aLCS.Transform(aShape.Location().Transformation());
+
+ if (aShape.ShapeType() == TopAbs_FACE) {
+ GEOM::GEOM_IMeasureOperations_ptr aMeasureOp =
+ myGeomGUI->GetGeomGen()->GetIMeasureOperations(getStudyId());
+ double Ox, Oy, Oz, Zx, Zy, Zz, Xx, Xy, Xz;
+
+ aMeasureOp->GetPosition(theGeomObj.get(), Ox, Oy, Oz, Zx, Zy, Zz, Xx, Xy, Xz);
+
+ if (aMeasureOp->IsDone()) {
+ gp_Pnt aPnt (Ox, Oy, Oz);
+ gp_Dir aDirN (Zx, Zy, Zz);
+ gp_Dir aDirX (Xx, Xy, Xz);
+ aLCS = gp_Ax3(aPnt, aDirN, aDirX);
+ }
+ }
+
+ return aLCS;
+}
#include <GEOMBase_Skeleton.h>
-
class CurveCreator_Curve;
class CurveCreator_Widget;
class QGroupBox;
+class QComboBox;
//=================================================================================
GEOM::short_array &theTypes,
GEOM::ListOfBool &theCloseds);
+ /**
+ * This method returns the current local coordinate system.
+ *
+ * \return local coordinate system.
+ */
+ gp_Ax3 GetActiveLocalCS();
+
+ /**
+ * This method returns the current working plane. Can be null.
+ *
+ * \return the current working plane.
+ */
+ GEOM::GeomObjPtr GetActiveWPlane();
+
+ /**
+ * This method add a local coordinate system of the selected object.
+ *
+ * \param theSelectedObject the selected object. It can be a planar face
+ * or an inported polyline.
+ * \param IsPlane true for planar face; false for imported polyline.
+ * \param theLCS the local coordinate system.
+ */
+ void AddLocalCS(GEOM::GeomObjPtr theSelectedObject,
+ const bool IsPlane,
+ const gp_Ax3 &theLCS);
+
+ /**
+ * This method converts the working plane object into
+ * the local coordinate system of the polyline.
+ *
+ * \param theGeomObj the working plane
+ * \return the local coordinate system
+ */
+ gp_Ax3 WPlaneToLCS(GEOM::GeomObjPtr theGeomObj);
+
protected slots:
void ClickOnOk();
bool ClickOnApply();
+ void ClickOnCancel();
void processStartedSubOperation( QWidget*, bool );
void processFinishedSubOperation( QWidget* );
+ void SetEditCurrentArgument();
void SelectionIntoArgument();
void ActivateThisDialog();
void onUpdatePreview();
+ void ActivateLocalCS();
private:
- CurveCreator_Curve *myCurve;
- CurveCreator_Widget *myEditorWidget;
- QGroupBox *myAddElementBox;
+ CurveCreator_Curve *myCurve;
+ CurveCreator_Widget *myEditorWidget;
+ QGroupBox *myAddElementBox;
+ QComboBox *myPlnComboBox;
+ QPushButton *myPlnButton;
+ QPushButton *myPlnSelButton;
+ QPushButton *myPolylineSelButton;
+ QLineEdit *myWPlaneLineEdit;
+ QLineEdit *myPolylineEdit;
+ QLineEdit *myEditCurrentArgument; /* Current LineEdit */
+ QList<gp_Ax3> myLCSList;
+ QList<GEOM::GeomObjPtr> myWPlaneList;
};
<source>POLYLINE_NAME</source>
<translation>Polyline</translation>
</message>
+ <message>
+ <source>POLYLINE_IMPORT</source>
+ <translation>Import polyline</translation>
+ </message>
<message>
<source>POLYLINE_ADD_SECTION</source>
<translation>Add section</translation>