From f1f709067a2c62996f38a5831d4f44cc6e23d983 Mon Sep 17 00:00:00 2001 From: rnc Date: Mon, 8 Oct 2012 10:16:55 +0000 Subject: [PATCH] EDF 1337 : Sketch 3D, allow definition of a point by angle + Added a global coordinate system mode for angles. + Added a cylindrical coordinates definition (with an optional height in angle widget) + Did some refactoring Doc and translations to be done soon --- src/EntityGUI/EntityGUI_3DSketcherDlg.cxx | 899 ++++++++++++--------- src/EntityGUI/EntityGUI_3DSketcherDlg.h | 56 +- src/EntityGUI/EntityGUI_Angles_QTD.ui | 44 +- src/EntityGUI/EntityGUI_Type_QTD.ui | 89 ++ src/EntityGUI/EntityGUI_Widgets.cxx | 14 + src/EntityGUI/EntityGUI_Widgets.h | 16 + src/EntityGUI/Makefile.am | 1 + src/GEOM/GEOM_Engine.cxx | 15 +- src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx | 49 +- src/GEOM_SWIG/gsketcher.py | 99 ++- 10 files changed, 853 insertions(+), 429 deletions(-) create mode 100644 src/EntityGUI/EntityGUI_Type_QTD.ui diff --git a/src/EntityGUI/EntityGUI_3DSketcherDlg.cxx b/src/EntityGUI/EntityGUI_3DSketcherDlg.cxx index b44cbd49c..07e506d6e 100755 --- a/src/EntityGUI/EntityGUI_3DSketcherDlg.cxx +++ b/src/EntityGUI/EntityGUI_3DSketcherDlg.cxx @@ -71,13 +71,20 @@ // GEOMImpl_Types.hxx and an enum in SOCC_ViewModel.h #include -enum -{ - NONE, - TYPE_LENGTH, - TYPE_ANGLE, - TYPE_TWO_ANGLES -}; +// TODO +// +// + Ecrire la partie absolute / relative pour les coordonnées angulaires Done +// + Ecrire les bons tests pour les coordonnées cylindriques Done +// + Finir refactoring des outils de display (displayLength) Done +// + Mettre en place la visualisation (côtes ...) pour les coordonnées cylindriques Done +// + Changement du mode de représentation (côtes) pour le cas absolu Half done +// + Dump pour les coordonnées cylindriques et +// report des modifs sur les autres types de coordonnées Done +// + Correction BUG coordonées cylindriques relatives --> la hauteur est absolue Done +// + Améliorer rendu des cotes pour coordonées cylindriques (tailles relatives +// de la cote rayon et de la cote hauteur) +// + Prendre en compte les remarques de Raphaël +// + Traductions enum { @@ -111,7 +118,6 @@ EntityGUI_3DSketcherDlg::EntityGUI_3DSketcherDlg (GeometryGUI* theGeometryGUI, Q myLineWidth(lineWidth), myGeometryGUI(theGeometryGUI), myLengthIORedoList() -// myLastAngleNormal() { QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT"))); QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_DLG_UNDO"))); @@ -127,16 +133,23 @@ EntityGUI_3DSketcherDlg::EntityGUI_3DSketcherDlg (GeometryGUI* theGeometryGUI, Q mainFrame()->RadioButton2->close(); mainFrame()->RadioButton3->close(); - GroupType = new DlgRef_3Radio(centralWidget()); - GroupType->GroupBox1->setTitle(tr("GEOM_COORDINATES_TYPE")); + GroupType = new EntityGUI_Type(centralWidget()); + GroupType->GroupType2->setTitle(tr("GEOM_COORDINATES_TYPE")); + GroupType->GroupType1->setTitle(tr("Scope")); // TODO translation GroupType->RadioButton1->setText(tr("GEOM_SKETCHER_ABS")); GroupType->RadioButton2->setText(tr("GEOM_SKETCHER_REL")); - GroupType->RadioButton3->setText(tr("Angles")); //TODO translation -// GroupType->RadioButton3->close(); - myTypeGroup = new QButtonGroup(this); - myTypeGroup->addButton(GroupType->RadioButton1, 0); - myTypeGroup->addButton(GroupType->RadioButton2, 1); - myTypeGroup->addButton(GroupType->RadioButton3, 2); + GroupType->RadioButton3->setText(tr("(X,Y,Z)")); //TODO translation + GroupType->RadioButton4->setText(tr("Angles")); //TODO translation + + myTypeGroup1 = new QButtonGroup(this); + myTypeGroup1->setExclusive(true); + myTypeGroup1->addButton(GroupType->RadioButton1, 0); + myTypeGroup1->addButton(GroupType->RadioButton2, 1); + + myTypeGroup2 = new QButtonGroup(this); + myTypeGroup2->setExclusive(true); + myTypeGroup2->addButton(GroupType->RadioButton3, 0); + myTypeGroup2->addButton(GroupType->RadioButton4, 1); Group3Spin = new EntityGUI_3Spin(centralWidget()); Group3Spin->GroupBox1->setTitle(tr("GEOM_SKETCHER_VALUES")); @@ -151,7 +164,8 @@ EntityGUI_3DSketcherDlg::EntityGUI_3DSketcherDlg (GeometryGUI* theGeometryGUI, Q GroupAngles->buttonApply->setText(tr("GEOM_SKETCHER_APPLY")); GroupAngles->buttonUndo->setIcon(image1); GroupAngles->buttonRedo->setIcon(image2); - GroupAngles->checkBox->setText(tr("Angle 2")); //TODO translation + GroupAngles->checkBox ->setText(tr("Angle 2")); //TODO translation + GroupAngles->checkBox_2->setText(tr("Height")); //TODO translation GroupControls = new EntityGUI_Controls(centralWidget()); GroupControls->GroupBox1->setTitle(tr("GEOM_CONTROLS")); @@ -204,16 +218,13 @@ void EntityGUI_3DSketcherDlg::Init() { myOK = false; myOrientation = OXY; - myPrsType = NONE; + myPrsType = prsType(); SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow(); myAnglePrs = dynamic_cast(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0)); myLengthPrs = dynamic_cast(((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0)); - //TEST localSelection(GEOM::GEOM_Object::_nil(), TopAbs_VERTEX); -// globalSelection(GEOM_PREVIEW); -// setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); /* Get setting of step value from file configuration */ double step = SUIT_Session::session()->resourceMgr()->doubleValue("Geometry", "SettingsGeomStep", 100.0); @@ -223,9 +234,10 @@ void EntityGUI_3DSketcherDlg::Init() initSpinBox(Group3Spin->SpinBox_DY, COORD_MIN, COORD_MAX, step, "length_precision"); initSpinBox(Group3Spin->SpinBox_DZ, COORD_MIN, COORD_MAX, step, "length_precision"); - initSpinBox(GroupAngles->SpinBox_DA , -180.0, 180.0, step, "angular_precision"); + initSpinBox(GroupAngles->SpinBox_DA , -360.0, 360.0, step, "angular_precision"); initSpinBox(GroupAngles->SpinBox_DA2, -90.0, 90.0, step, "angular_precision"); initSpinBox(GroupAngles->SpinBox_DL , COORD_MIN, COORD_MAX, step, "length_precision"); + initSpinBox(GroupAngles->SpinBox_DH , COORD_MIN, COORD_MAX, step, "length_precision"); Group3Spin->SpinBox_DX->setValue(0.0); Group3Spin->SpinBox_DY->setValue(0.0); @@ -234,10 +246,13 @@ void EntityGUI_3DSketcherDlg::Init() GroupAngles->SpinBox_DA->setValue(0.0); GroupAngles->SpinBox_DA2->setValue(0.0); GroupAngles->SpinBox_DL->setValue(0.0); + GroupAngles->SpinBox_DH->setValue(0.0); GroupAngles->radioButton_1->setChecked(true); GroupAngles->checkBox->setChecked(false); + GroupAngles->checkBox_2->setChecked(false); GroupAngles->SpinBox_DA2->setEnabled(false); + GroupAngles->SpinBox_DH->setEnabled(false); GroupControls->CheckBox1->setChecked(true); GroupControls->CheckBox2->setChecked(true); @@ -254,29 +269,32 @@ void EntityGUI_3DSketcherDlg::Init() connect(myGeomGUI->getApp()->selectionMgr(), SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument())); - connect(Group3Spin->buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnAddPoint())); - connect(Group3Spin->buttonUndo, SIGNAL(clicked()), this, SLOT(ClickOnUndo())); - connect(Group3Spin->buttonRedo, SIGNAL(clicked()), this, SLOT(ClickOnRedo())) ; + connect(Group3Spin->buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnAddPoint())); + connect(Group3Spin->buttonUndo, SIGNAL(clicked()), this, SLOT(ClickOnUndo())); + connect(Group3Spin->buttonRedo, SIGNAL(clicked()), this, SLOT(ClickOnRedo())) ; connect(GroupAngles->buttonApply, SIGNAL(clicked()), this, SLOT(ClickOnAddPoint())); connect(GroupAngles->buttonUndo, SIGNAL(clicked()), this, SLOT(ClickOnUndo())); connect(GroupAngles->buttonRedo, SIGNAL(clicked()), this, SLOT(ClickOnRedo())) ; - connect(myTypeGroup, SIGNAL(buttonClicked(int)), this, SLOT(TypeClicked(int))); + connect(myTypeGroup1, SIGNAL(buttonClicked(int)), this, SLOT(TypeClicked(int))); + connect(myTypeGroup2, SIGNAL(buttonClicked(int)), this, SLOT(TypeClicked(int))); - connect(Group3Spin->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); - connect(Group3Spin->SpinBox_DY, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); - connect(Group3Spin->SpinBox_DZ, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(Group3Spin->SpinBox_DX, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(Group3Spin->SpinBox_DY, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(Group3Spin->SpinBox_DZ, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); - connect(GroupAngles->SpinBox_DA, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); - connect(GroupAngles->SpinBox_DA2, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); - connect(GroupAngles->SpinBox_DL, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(GroupAngles->SpinBox_DA, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(GroupAngles->SpinBox_DA2, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(GroupAngles->SpinBox_DL, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); + connect(GroupAngles->SpinBox_DH, SIGNAL(valueChanged(double)), this, SLOT(ValueChangedInSpinBox(double))); connect(GroupAngles->radioButton_1, SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ; connect(GroupAngles->radioButton_2, SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ; connect(GroupAngles->radioButton_3, SIGNAL(clicked (bool)), this, SLOT(ButtonClicked(bool))) ; connect(GroupAngles->checkBox, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ; + connect(GroupAngles->checkBox_2, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ; connect(GroupControls->CheckBox1, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ; connect(GroupControls->CheckBox2, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ; connect(GroupControls->CheckBox3, SIGNAL(clicked (bool)), this, SLOT(BoxChecked (bool))) ; @@ -291,6 +309,10 @@ void EntityGUI_3DSketcherDlg::Init() GroupControls->CheckBox3->click(); UpdateButtonsState(); + + myMode = 0; + myCoordType = 0; + GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth); } @@ -298,10 +320,24 @@ void EntityGUI_3DSketcherDlg::Init() // function : TypeClicked() // purpose : Radio button management //================================================================================= -void EntityGUI_3DSketcherDlg::TypeClicked (int mode) +void EntityGUI_3DSketcherDlg::TypeClicked (int id) { - if (mode == myMode) return; - + QButtonGroup* send = (QButtonGroup*) sender(); + + int coordType = myCoordType; + int mode = myMode; + + if (send == myTypeGroup1) + { + if(id == myMode) return; + mode = id; + } + else if (send == myTypeGroup2) + { + if (id == myCoordType) return; + coordType = id; + } + GroupAngles->hide(); Group3Spin->show(); @@ -317,31 +353,35 @@ void EntityGUI_3DSketcherDlg::TypeClicked (int mode) Group3Spin->SpinBox_DY->text().toDouble(&oky); Group3Spin->SpinBox_DZ->text().toDouble(&okz); - if (mode == 0) { // XYZ - Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_X2")); - Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_Y2")); - Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_Z2")); - if (myMode == 1) - { - if (okx) Group3Spin->SpinBox_DX->setValue(xyz.x + Group3Spin->SpinBox_DX->value()); - if (oky) Group3Spin->SpinBox_DY->setValue(xyz.y + Group3Spin->SpinBox_DY->value()); - if (okz) Group3Spin->SpinBox_DZ->setValue(xyz.z + Group3Spin->SpinBox_DZ->value()); + if (coordType == 0) // Cartesian coordinates + { + if (mode == 0) { // XYZ + Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_X2")); + Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_Y2")); + Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_Z2")); + if (myCoordType == 0 && myMode == 1) + { + if (okx) Group3Spin->SpinBox_DX->setValue(xyz.x + Group3Spin->SpinBox_DX->value()); + if (oky) Group3Spin->SpinBox_DY->setValue(xyz.y + Group3Spin->SpinBox_DY->value()); + if (okz) Group3Spin->SpinBox_DZ->setValue(xyz.z + Group3Spin->SpinBox_DZ->value()); + } + Group3Spin->buttonApply->setFocus(); } - Group3Spin->buttonApply->setFocus(); - } - else if (mode == 1) { // DXDYDZ - Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_DX2")); - Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_DY2")); - Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_DZ2")); - if (myMode == 0) - { - if (okx) Group3Spin->SpinBox_DX->setValue(Group3Spin->SpinBox_DX->value() - xyz.x); - if (oky) Group3Spin->SpinBox_DY->setValue(Group3Spin->SpinBox_DY->value() - xyz.y); - if (okz) Group3Spin->SpinBox_DZ->setValue(Group3Spin->SpinBox_DZ->value() - xyz.z); + else if (mode == 1) { // DXDYDZ + Group3Spin->TextLabel1->setText(tr("GEOM_SKETCHER_DX2")); + Group3Spin->TextLabel2->setText(tr("GEOM_SKETCHER_DY2")); + Group3Spin->TextLabel3->setText(tr("GEOM_SKETCHER_DZ2")); + if (myCoordType == 0 && myMode == 0) + { + if (okx) Group3Spin->SpinBox_DX->setValue(Group3Spin->SpinBox_DX->value() - xyz.x); + if (oky) Group3Spin->SpinBox_DY->setValue(Group3Spin->SpinBox_DY->value() - xyz.y); + if (okz) Group3Spin->SpinBox_DZ->setValue(Group3Spin->SpinBox_DZ->value() - xyz.z); + } + Group3Spin->buttonApply->setFocus(); } - Group3Spin->buttonApply->setFocus(); } - else if (mode == 2) { // Angles and Length + else if (coordType == 1) // Angles and Length + { Group3Spin->hide(); GroupAngles->show(); GroupAngles->buttonApply->setFocus(); @@ -352,6 +392,7 @@ void EntityGUI_3DSketcherDlg::TypeClicked (int mode) Group3Spin->SpinBox_DZ->blockSignals(blocked); myMode = mode; + myCoordType = coordType; updateGeometry(); resize(minimumSizeHint()); @@ -370,44 +411,24 @@ void EntityGUI_3DSketcherDlg::ClickOnAddPoint() showError(msg); return; } - - // Display and store angle dimensions interactive objects in Prs - if (GroupType->RadioButton3->isChecked()) // ANGLES - { - double anAngle2 = 0.0; - if (GroupAngles->checkBox->isChecked()) - anAngle2 = GroupAngles->SpinBox_DA2->value(); - - // Store angle dimensions - displayAngle(GroupAngles->SpinBox_DA->value(), anAngle2, - GroupAngles->SpinBox_DL->value(), myOrientation, /*store =*/true); - // Store length dimensions - displayLength(GroupAngles->SpinBox_DL->value(), /*store =*/true, /*type=*/myPrsType); - } - - // Display and store store length dimension interactive object in Prs - if (GroupType->RadioButton1->isChecked() || // ABSOLUTE or RELATIVE coordinates - GroupType->RadioButton2->isChecked()) - { - displayLength(-1, /*store=*/true); - } + + myPrsType = prsType(); + + if(myMode == 1) + displayDimensions( /*store = */true); myPointsList.append(getCurrentPoint()); - myPrsTypeList.push_back(myPrsType); - - // Clean redo lists myRedoList.clear(); - myPrsTypeRedoList.clear(); myLengthIORedoList.Clear(); myAngleIORedoList.Clear(); - if (myMode == 1) + if (myCoordType == 0 && myMode == 1) // RELATIVE CARTESIAN COORDINATES { Group3Spin->SpinBox_DX->setValue(0.0); Group3Spin->SpinBox_DY->setValue(0.0); Group3Spin->SpinBox_DZ->setValue(0.0); } - else if (myMode == 2) + else if (myCoordType == 1 && myMode == 1) // RELATIVE ANGULAR COORDINATES { GroupAngles->SpinBox_DA->setValue(0.0); GroupAngles->SpinBox_DL->setValue(0.0); @@ -426,9 +447,14 @@ void EntityGUI_3DSketcherDlg::ClickOnAddPoint() //================================================================================= void EntityGUI_3DSketcherDlg::UpdateButtonsState() { - if (myPointsList.count() == 0) GroupType->RadioButton1->click(); + if (myPointsList.count() == 0) + { + GroupType->RadioButton1->click(); + GroupType->RadioButton3->click(); + } GroupType->RadioButton2->setEnabled(myPointsList.count() > 0); GroupType->RadioButton3->setEnabled(myPointsList.count() > 0); + GroupType->RadioButton4->setEnabled(myPointsList.count() > 0); Group3Spin->buttonUndo->setEnabled(myPointsList.count() > 0); Group3Spin->buttonRedo->setEnabled(myRedoList.count() > 0); GroupAngles->buttonUndo->setEnabled(myPointsList.count() > 0); @@ -480,35 +506,15 @@ void EntityGUI_3DSketcherDlg::UpdatePointCoordinates() void EntityGUI_3DSketcherDlg::ClickOnUndo() { if (myPointsList.count() > 0) { - myRedoList.append(myPointsList.takeLast()); - UpdateButtonsState(); - GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth); + + myRedoList.append(myPointsList.last()); // Erase dimensions presentations SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow(); ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true); ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true); - - if (myPrsTypeList.back() != NONE) - { - // Remove last prepended IO - removeLastIOFromPrs(TYPE_LENGTH); - } - if (myPrsTypeList.back() == TYPE_ANGLE || - myPrsTypeList.back() == TYPE_TWO_ANGLES) - { - // Remove first Angle IO from presentation - removeLastIOFromPrs(TYPE_ANGLE); - if (myPrsTypeList.back() == TYPE_TWO_ANGLES) - { - // Remove second Angle IO - removeLastIOFromPrs(TYPE_ANGLE); - } - } - - // Erase last action type and store it in redo list - myPrsTypeRedoList.push_back(myPrsTypeList.back()); - myPrsTypeList.pop_back(); + + removeLastIOFromPrs(); // Display modified presentation if (isLengthVisible) @@ -516,6 +522,11 @@ void EntityGUI_3DSketcherDlg::ClickOnUndo() if (isAngleVisible) ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs); + // Remove last point from list + myPointsList.removeLast(); + GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth); + UpdateButtonsState(); + // Update of point coordinates in the control groupbox UpdatePointCoordinates(); @@ -530,33 +541,15 @@ void EntityGUI_3DSketcherDlg::ClickOnUndo() void EntityGUI_3DSketcherDlg::ClickOnRedo() { if (myRedoList.count() > 0) { - myPointsList.append(myRedoList.takeLast()); - UpdateButtonsState(); - GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth); + + myPointsList.append(myRedoList.last()); // Erase dimensions presentations SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow(); ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true); ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true); - - if (myPrsTypeRedoList.back() != NONE) - restoreLastIOToPrs(TYPE_LENGTH); - - if (myPrsTypeRedoList.back() == TYPE_ANGLE || - myPrsTypeRedoList.back() == TYPE_TWO_ANGLES) - { - // Add a first IO from the Redo list - restoreLastIOToPrs(TYPE_ANGLE); - if (myPrsTypeRedoList.back() == TYPE_TWO_ANGLES) - { - // Add a second IO from the Redo list - restoreLastIOToPrs(TYPE_ANGLE); - } - } - - // Record last prs type - myPrsTypeList.push_back(myPrsTypeRedoList.back()); - myPrsTypeRedoList.pop_back(); + + restoreLastIOToPrs(); // Display modified presentation if (isLengthVisible) @@ -564,6 +557,11 @@ void EntityGUI_3DSketcherDlg::ClickOnRedo() if (isAngleVisible) ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs); + // Remove last point from redo list + myRedoList.removeLast(); + GEOMBase_Helper::displayPreview(true, false, true, true, myLineWidth); + UpdateButtonsState(); + // Update of point coordinates in the control groupbox UpdatePointCoordinates(); @@ -575,17 +573,18 @@ void EntityGUI_3DSketcherDlg::ClickOnRedo() // function : removeLastIO() // purpose : //================================================================================= -void EntityGUI_3DSketcherDlg::removeLastIOFromPrs (int type) +void EntityGUI_3DSketcherDlg::removeLastIOFromPrs () { AIS_ListOfInteractive anIOList; - - if (type == TYPE_LENGTH) + XYZ Last = getLastPoint(); + + for (int l = 0; lGetObjects(anIOList); myLengthIORedoList.Prepend(anIOList.First()); // Store last prepended Length IO in redo list myLengthPrs->RemoveFirst(); // Remove it from myLengthPrs } - if (type == TYPE_ANGLE) + for (int a = 0; aGetObjects(anIOList); myAngleIORedoList.Prepend(anIOList.First()); // Store last prepended Angle IO in redo list @@ -597,14 +596,16 @@ void EntityGUI_3DSketcherDlg::removeLastIOFromPrs (int type) // function : restoreLastIO() // purpose : //================================================================================= -void EntityGUI_3DSketcherDlg::restoreLastIOToPrs (int type) +void EntityGUI_3DSketcherDlg::restoreLastIOToPrs () { - if (type == TYPE_LENGTH) + XYZ LastDeleted = myRedoList.last(); + + for (int l = 0; lPrependObject(myLengthIORedoList.First()); // Restore last removed IO myLengthIORedoList.RemoveFirst(); // Remove it from redo list - } - if (type == TYPE_ANGLE) + } + for (int a = 0; aPrependObject(myAngleIORedoList.First()); // Restore last removed IO myAngleIORedoList.RemoveFirst(); // Remove it from redo list @@ -720,7 +721,23 @@ void EntityGUI_3DSketcherDlg::BoxChecked (bool checked) SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow(); if (send == GroupAngles->checkBox) + { GroupAngles->SpinBox_DA2->setEnabled(checked); + if(checked) + { + GroupAngles->SpinBox_DH->setEnabled(false); + GroupAngles->checkBox_2->setChecked(false); + } + } + else if (send == GroupAngles->checkBox_2) + { + GroupAngles->SpinBox_DH->setEnabled(checked); + if(checked) + { + GroupAngles->SpinBox_DA2->setEnabled(false); + GroupAngles->checkBox->setChecked(false); + } + } else if (send == GroupControls->CheckBox1) { @@ -854,6 +871,7 @@ bool EntityGUI_3DSketcherDlg::execute (ObjectList& objects) aParameters << xyz.params; } +// MESSAGE("aCommands.last() = "<< aCommands.last().toStdString()); GEOM::GEOM_ICurvesOperations_var anOper = GEOM::GEOM_ICurvesOperations::_narrow(getOperation()); //GEOM::GEOM_Object_var anObj = anOper->Make3DSketcher(aCoordsArray); GEOM::GEOM_Object_var anObj = anOper->Make3DSketcherCommand(aCommands.join(":").toLatin1().constData()); @@ -875,9 +893,10 @@ void EntityGUI_3DSketcherDlg::SetDoubleSpinBoxStep (double step) Group3Spin->SpinBox_DX->setSingleStep(step); Group3Spin->SpinBox_DY->setSingleStep(step); Group3Spin->SpinBox_DZ->setSingleStep(step); - GroupAngles->SpinBox_DA->setSingleStep(step); - GroupAngles->SpinBox_DL->setSingleStep(step); + GroupAngles->SpinBox_DA ->setSingleStep(step); GroupAngles->SpinBox_DA2->setSingleStep(step); + GroupAngles->SpinBox_DL->setSingleStep(step); + GroupAngles->SpinBox_DH->setSingleStep(step); } //================================================================================= @@ -947,60 +966,110 @@ EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getCurrentPoint() const SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); int aPrecision = resMgr->integerValue("Geometry", "length_precision", 7); + + bool spherical = GroupAngles->checkBox->isChecked(); + bool cylindrical = GroupAngles->checkBox_2->isChecked(); - if (myMode == 2) { + if (myCoordType == 1) + { if (GroupAngles->radioButton_1->isChecked()) - xyz.command = "OXY "; + xyz.command = "OXY"; else if (GroupAngles->radioButton_2->isChecked()) - xyz.command = "OYZ "; + xyz.command = "OYZ"; + else + xyz.command = "OXZ"; + + if (cylindrical) // Cylindrical coordinates (radius, angle, height) + xyz.command += "C"; else - xyz.command = "OXZ "; + xyz.command += "S"; // Spherical coordinates (radius, angle1, angle2) --> polar if angle2 = 0 + + if (myMode == 0) // Absolute coordinates + xyz.command += "A "; + else if (myMode == 1) // Relative coordinates + xyz.command += "R "; + double anAngle = GroupAngles->SpinBox_DA->value(); double aLength = GroupAngles->SpinBox_DL->value(); double anAngle2 = 0.0; QString da2 = "0"; - if (GroupAngles->checkBox->isChecked()) { + if (spherical) { // Spherical coordinates (radius, angle1, angle2) anAngle2 = GroupAngles->SpinBox_DA2->value(); da2 = GroupAngles->SpinBox_DA2->text(); } + + double aHeight = 0.0; + QString dh = "0"; + if (cylindrical) { + aHeight = GroupAngles->SpinBox_DH->value(); + dh = GroupAngles->SpinBox_DH->text(); + } xyz.command += - QString::number(anAngle, 'g', aPrecision) + " " + - QString::number(anAngle2, 'g', aPrecision) + " " + - QString::number(aLength, 'g', aPrecision); + QString::number(anAngle, 'g', aPrecision) + " "; xyz.params = - GroupAngles->SpinBox_DA->text() + ":" + - da2 + ":" + + GroupAngles->SpinBox_DA->text() + ":"; + + if(cylindrical) + { + xyz.command += + QString::number(aHeight, 'g', aPrecision) + " "; + xyz.params += + dh + ":"; + } + else // Spherical or polar coordinates + { + xyz.command += + QString::number(anAngle2, 'g', aPrecision) + " "; + xyz.params += + dh + ":"; + } + + xyz.command += + QString::number(aLength, 'g', aPrecision); + xyz.params += GroupAngles->SpinBox_DL->text(); + // Calculate point coordinates for preview anAngle = anAngle * M_PI/180.0; anAngle2 = anAngle2 * M_PI/180.0; double aProjectedLength = aLength * cos(anAngle2); - + XYZ xyzP = getLastPoint(); + if (myMode == 0) + xyzP.x=xyzP.y=xyzP.z=0.0; if (GroupAngles->radioButton_1->isChecked()) // OXY { xyz.x = xyzP.x + aProjectedLength * cos(anAngle); xyz.y = xyzP.y + aProjectedLength * sin(anAngle); - xyz.z = xyzP.z + aLength * sin(anAngle2); + if (cylindrical) + xyz.z = xyzP.z + aHeight; + else + xyz.z = xyzP.z + aLength * sin(anAngle2); } else if (GroupAngles->radioButton_2->isChecked()) // OYZ { xyz.y = xyzP.y + aProjectedLength * cos(anAngle); xyz.z = xyzP.z + aProjectedLength * sin(anAngle); - xyz.x = xyzP.x + aLength * sin(anAngle2); + if (cylindrical) + xyz.x = xyzP.x + aHeight; + else + xyz.x = xyzP.x + aLength * sin(anAngle2); } else // OXZ { xyz.z = xyzP.z + aProjectedLength * sin(anAngle); xyz.x = xyzP.x + aProjectedLength * cos(anAngle); - xyz.y = xyzP.y + aLength * sin(anAngle2); + if (cylindrical) + xyz.y = xyzP.y + aHeight; + else + xyz.y = xyzP.y + aLength * sin(anAngle2); } } - else { + else if(myCoordType == 0) { if (myMode == 0) { // XYZ xyz.x = Group3Spin->SpinBox_DX->value(); xyz.y = Group3Spin->SpinBox_DY->value(); @@ -1028,9 +1097,113 @@ EntityGUI_3DSketcherDlg::XYZ EntityGUI_3DSketcherDlg::getCurrentPoint() const Group3Spin->SpinBox_DY->text() + ":" + Group3Spin->SpinBox_DZ->text(); } + // Update point presentation type + xyz.A = myPrsType.A; // Number of angle diomensions + xyz.L = myPrsType.L; // Number of length dimensions + return xyz; } + +//================================================================================= +// function : getPresentationPlane() +// purpose : returns the suitable plane for right +// relative positioning of dimension presentations +//================================================================================= +gp_Dir EntityGUI_3DSketcherDlg::getPresentationPlane() const +{ + MESSAGE("EntityGUI_3DSketcherDlg::getPresentationPlane()") + bool withAngle = (myCoordType == 1); + bool twoAngles = GroupAngles->checkBox->isChecked(); + + XYZ Last = getLastPoint(); + XYZ Current = getCurrentPoint(); + XYZ Penultimate = getPenultimatePoint(); + + gp_Pnt P1 = gp_Pnt(Last.x,Last.y,Last.z); + if (myMode == 0) // Absolute coordinates + P1 = gp::Origin(); + + gp_Pnt P2 = gp_Pnt(Current.x,Current.y,Current.z); + gp_Pnt P3 = gp_Pnt(Penultimate.x,Penultimate.y,Penultimate.z); + + gp_Vec Vec1(P1,P2); + gp_Vec Vec2(P1,P3); + gp_Vec Vec3 = Vec1; + + gp_Dir aNormal; // Normal defining the plane of the presentation + + if (withAngle) // If one angle + { + switch(myOrientation) + { + case OXY: + { + if (Vec1.CrossMagnitude(gp::DZ()) > Precision::Confusion()) + aNormal = gp::DZ().Crossed(gp_Dir(Vec1)); // --> the plane is orthogonal to the angle presentation + else // plane and contains the current edge + aNormal = gp::DY(); + + if (twoAngles) // If two angles + { + gp_XYZ Vec1_XY(Vec1.X(),Vec1.Y(),0.0);// --> define Vec3 as the projection of the current + Vec3 = gp_Vec(Vec1_XY); // edge on the plane chosen for the first angle + } + break; + } + case OYZ: + { + if (Vec1.CrossMagnitude(gp::DX()) > Precision::Confusion()) + aNormal = gp::DX().Crossed(gp_Dir(Vec1)); + else + aNormal = gp::DZ(); + + if (twoAngles) + { + gp_XYZ Vec1_YZ(0.0,Vec1.Y(),Vec1.Z()); + Vec3 = gp_Vec(Vec1_YZ); + } + break; + } + case OXZ: + { + if (Vec1.CrossMagnitude(gp::DY()) > Precision::Confusion()) + aNormal = gp::DY().Crossed(gp_Dir(Vec1)); + else + aNormal = gp::DZ(); + + if (twoAngles) + { + gp_XYZ Vec1_XZ(Vec1.X(),0.0,Vec1.Z()); + Vec3 = gp_Vec(Vec1_XZ); + } + break; + } + } + + if(twoAngles // If two angles + && Abs(Vec1.CrossMagnitude(Vec3)) > Precision::Confusion()) + { + aNormal = gp_Dir(Vec1.Crossed(Vec3));// --> set the normal as the cross product of + } // the current edge with its projection + } // it ensures that the dimension changes + // side when the angle becomes negative + else + { + // Check colinearity + if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion()) + { + Vec2 = gp_Vec(gp::DX()); + if (Abs(Vec1.CrossMagnitude(Vec2)) < Precision::Confusion()) + { + Vec2 = gp_Vec(gp::DY()); + } + } + aNormal = gp_Dir(Vec1.Crossed(Vec2)); // If no angles --> the plane is the one formed by + } // the last edge and the current one + return aNormal; +} + //================================================================ // Function : displayPreview // Purpose : Method for displaying preview of resulting shape @@ -1084,22 +1257,12 @@ void EntityGUI_3DSketcherDlg::displayPreview (GEOM::GEOM_Object_ptr object, getDisplayer()->SetColor(line_color); - // Display local trihedron if the mode is relatives coordinates or angles - if (myMode == 1 || myMode == 2) + // Display local trihedron if the mode is relative + if (myMode == 1) displayTrihedron(2); // Display preview of suitable dimension presentations - if (myMode == 2) // ANGLES - { - double anAngle2 = 0.0; - if (GroupAngles->checkBox->isChecked()) - anAngle2 = GroupAngles->SpinBox_DA2->value(); - - displayAngle(GroupAngles->SpinBox_DA->value(), anAngle2, GroupAngles->SpinBox_DL->value(), myOrientation); - displayLength(GroupAngles->SpinBox_DL->value(), /*store=*/false, /*type=*/myPrsType); - } - if (myMode == 0 || myMode == 1) // COORDINATES - displayLength(); + displayDimensions(false); getDisplayer()->UnsetName(); @@ -1131,280 +1294,256 @@ void EntityGUI_3DSketcherDlg::displayTrihedron (int selMode) } //================================================================ -// Function : displayAngle() -// Purpose : Method for displaying angle dimensions +// Function : displayDimensions( bool store ) +// Purpose : Method for displaying dimensions if store = true +// the presentation is stored in a list //================================================================ -void EntityGUI_3DSketcherDlg::displayAngle (double theAngle1, double theAngle2, - double theLength, int theOrientation, bool store) +void EntityGUI_3DSketcherDlg::displayDimensions (bool store) { - if (Abs(theAngle2 - 90.0) < Precision::Angular() || - theLength < Precision::Confusion()) - return; - - SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow(); - + myPrsType = prsType(); XYZ Last = getLastPoint(); + if (myMode == 0) // Absolute coordinates + Last.x=Last.y=Last.z=0.0; + XYZ Current = getCurrentPoint(); gp_Pnt Last_Pnt(Last.x,Last.y,Last.z); gp_Pnt Current_Pnt(Current.x,Current.y,Current.z); gp_Pnt P1, P2; - - bool twoAngles = GroupAngles->checkBox->isChecked(); - - switch(theOrientation) + gp_Dir aNormal = getPresentationPlane(); + + if (myCoordType == 0) + { + displayLength(Last_Pnt, Current_Pnt, aNormal, store); +// myPrsType = TYPE_LENGTH; + } + if (myCoordType == 1) // ANGLES { - case OXY: + bool spherical = GroupAngles->checkBox->isChecked(); + bool cylindrical = GroupAngles->checkBox_2->isChecked(); + + double anAngle1 = GroupAngles->SpinBox_DA->value(); + double aLength = GroupAngles->SpinBox_DL->value(); + + switch(myOrientation) { - P1 = gp_Pnt(Last.x + theLength,Last.y,Last.z); // X direction - P2 = gp_Pnt(Last.x + theLength * cos(theAngle1 * M_PI / 180.), - Last.y + theLength * sin(theAngle1 * M_PI / 180.), - Last.z); - break; + case OXY: + { + P1 = gp_Pnt(Last.x + aLength,Last.y,Last.z); // X direction + P2 = gp_Pnt(Last.x + aLength * cos(anAngle1 * M_PI / 180.), + Last.y + aLength * sin(anAngle1 * M_PI / 180.), + Last.z); + break; + } + case OYZ: + { + P1 = gp_Pnt(Last.x, Last.y + aLength,Last.z); // Y direction + P2 = gp_Pnt(Last.x, + Last.y + aLength * cos(anAngle1 * M_PI / 180.), + Last.z + aLength * sin(anAngle1 * M_PI / 180.)); + break; + } + case OXZ: + { + P1 = gp_Pnt(Last.x + aLength,Last.y,Last.z); // X direction + P2 = gp_Pnt(Last.x + aLength * cos(anAngle1 * M_PI / 180.) , + Last.y, + Last.z + aLength * sin(anAngle1 * M_PI / 180.)); + break; + } } - case OYZ: + + if(!cylindrical) + displayLength(Last_Pnt, Current_Pnt, aNormal, store); + displayAngle(anAngle1, Last_Pnt, P1, P2, store); + + if(spherical) { - P1 = gp_Pnt(Last.x, Last.y + theLength,Last.z); // Y direction - P2 = gp_Pnt(Last.x, - Last.y + theLength * cos(theAngle1 * M_PI / 180.), - Last.z + theLength * sin(theAngle1 * M_PI / 180.)); - break; + double anAngle2 = GroupAngles->SpinBox_DA2->value(); + displayAngle(anAngle2, Last_Pnt, P2, Current_Pnt, store); } - case OXZ: + if(cylindrical) { - P1 = gp_Pnt(Last.x + theLength,Last.y,Last.z); // X direction - P2 = gp_Pnt(Last.x + theLength * cos(theAngle1 * M_PI / 180.) , - Last.y, - Last.z + theLength * sin(theAngle1 * M_PI / 180.)); - break; + displayLength(Last_Pnt, P2, aNormal, store); // Radius + displayLength(P2, Current_Pnt, aNormal.Reversed(), store); // Height } } +} - TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(P1); - TopoDS_Vertex V2 = BRepBuilderAPI_MakeVertex(P2); - TopoDS_Vertex LastV = BRepBuilderAPI_MakeVertex(Last_Pnt); - TopoDS_Vertex CurV = BRepBuilderAPI_MakeVertex(Current_Pnt); - TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge(LastV, V1); - TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge(LastV, V2); - TopoDS_Edge anEdge3 = BRepBuilderAPI_MakeEdge(LastV, CurV); - - gce_MakePln gce_MP (Last_Pnt, P1, P2); - Handle(Geom_Plane) aPlane = new Geom_Plane(gce_MP.Value()); - - // Convert angles to string - std::string Angle1_str = doubleToString(theAngle1); - std::string Angle2_str = doubleToString(theAngle2); - - // Create interactive object - Handle(AIS_AngleDimension) anAngleIO = new AIS_AngleDimension - (anEdge1, anEdge2, aPlane, theAngle1 * M_PI / 180., - TCollection_ExtendedString(Angle1_str.c_str())); - anAngleIO->SetArrowSize((theAngle1 * M_PI / 180) * (theLength/20)); - - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); - int w = resMgr->integerValue("Geometry", "measures_line_width", 1); - - Handle(Prs3d_AngleAspect) asp = new Prs3d_AngleAspect(); - asp->LineAspect()->SetWidth(w); - anAngleIO->Attributes()->SetAngleAspect(asp); - - SOCC_Prs* aSPrs = dynamic_cast - (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0)); - +//================================================================ +// Function : displayAngle() +// Purpose : Method for displaying angle dimensions +//================================================================ +void EntityGUI_3DSketcherDlg::displayAngle (double theAngle, + gp_Pnt P0, + gp_Pnt P1, + gp_Pnt P2, + bool store) +{ + SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow(); + + // Creation of the AIS object + Handle(AIS_AngleDimension) anAngleIO = createAISAngleDimension(theAngle, + P0, + P1, + P2); + if (anAngleIO == NULL) + return; + if (store) { // Erase dimensions presentations ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true); myAnglePrs->PrependObject(anAngleIO); - + // Display modified presentation if (isAngleVisible) ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs); + + // Update dimension presentation angle count for later undo / redo + myPrsType.A += 1; } - else if (aSPrs) - { - aSPrs->AddObject(anAngleIO); - } - myPrsType = TYPE_ANGLE; // Overwrite type with ANGLE - - if (twoAngles) + else if ( isAngleVisible) { - gce_MakePln gce_MP2(Last_Pnt, P2, Current_Pnt); - Handle(Geom_Plane) aPlane2 = new Geom_Plane(gce_MP2.Value()); - - Handle(AIS_AngleDimension) anAngle2IO = - new AIS_AngleDimension(anEdge2, anEdge3, aPlane2, theAngle2 * M_PI / 180., - TCollection_ExtendedString(Angle2_str.c_str())); - anAngle2IO->SetArrowSize((theAngle2 * M_PI / 180) * (theLength/20)); - - anAngle2IO->Attributes()->SetAngleAspect(asp); - - if (store) - { - // Erase dimensions presentations - ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myAnglePrs, true); - myAnglePrs->PrependObject(anAngle2IO); - - // Display modified presentation - if (isAngleVisible) - ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myAnglePrs); - } - else if (aSPrs) + SOCC_Prs* aSPrs = dynamic_cast + (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0)); + + if (aSPrs) { - aSPrs->AddObject(anAngle2IO); + aSPrs->AddObject(anAngleIO); + GEOMBase_Helper::displayPreview(aSPrs, true, true); } - - myPrsType = TYPE_TWO_ANGLES; // Overwrite type with TWO_ANGLES - } - - if (!store && isAngleVisible) - { - GEOMBase_Helper::displayPreview(aSPrs, true, true); } } + //================================================================ // Function : displayLength() -// Purpose : Method for displaying length dimensions +// Purpose : Method for displaying length dimensions for a segment +// creation step //================================================================ -void EntityGUI_3DSketcherDlg::displayLength (double theLength, bool store, int type) +void EntityGUI_3DSketcherDlg::displayLength (gp_Pnt P1, + gp_Pnt P2, + gp_Dir theNormal, + bool store) { SUIT_ViewWindow* vw = SUIT_Session::session()->activeApplication()->desktop()->activeWindow(); - - XYZ Last = getLastPoint(); - XYZ Current = getCurrentPoint(); - XYZ Penultimate = getPenultimatePoint(); - bool withAngle = (type == TYPE_ANGLE || type == TYPE_TWO_ANGLES); - bool twoAngles = (type == TYPE_TWO_ANGLES); + double aLength = P1.Distance(P2); - double aLength = 0.0; - - if (theLength < 0) // Calculate length if not given - { - aLength = sqrt((Last.x - Current.x)*(Last.x - Current.x) + - (Last.y - Current.y)*(Last.y - Current.y) + - (Last.z - Current.z)*(Last.z - Current.z)); - } - else - aLength = theLength; - - if (aLengthLineAspect()->SetWidth(w); anIO->Attributes()->SetLengthAspect(asp); + + return anIO; +} - if (store) - { - // Erase length dimensions presentation - ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Erase(myLengthPrs, true); - myLengthPrs->PrependObject(anIO); +//================================================================ +// Function : createAISAngleDimension() +// Purpose : Method for creation of an angle dimension object +// Returns an Handle on the AIS_AngleDimension obect +//================================================================ +Handle(AIS_AngleDimension) EntityGUI_3DSketcherDlg::createAISAngleDimension(double theAngle, + gp_Pnt P0, + gp_Pnt P1, + gp_Pnt P2) +{ + // Length of the built segment + double aLength = P0.Distance(P1); + + // Check input data + if (Abs(theAngle - 90.0) < Precision::Angular() || + aLength < Precision::Confusion()) + return NULL; + + // Convert angles to string + std::string Angle_str = doubleToString(theAngle); + + // Construction of the plane + gce_MakePln gce_MP2(P0, P1, P2); + Handle(Geom_Plane) aPlane = new Geom_Plane(gce_MP2.Value()); + + TopoDS_Vertex V0 = BRepBuilderAPI_MakeVertex(P0); + TopoDS_Vertex V1 = BRepBuilderAPI_MakeVertex(P1); + TopoDS_Vertex V2 = BRepBuilderAPI_MakeVertex(P2); + + TopoDS_Edge anEdge1 = BRepBuilderAPI_MakeEdge(V0, V1); + TopoDS_Edge anEdge2 = BRepBuilderAPI_MakeEdge(V0, V2); - // Display modified presentation - if (isLengthVisible) - ((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->Display(myLengthPrs); - } - else if (isLengthVisible) - { - SOCC_Prs* aSPrs = dynamic_cast - (((SOCC_Viewer*)(vw->getViewManager()->getViewModel()))->CreatePrs(0)); - if (aSPrs) - { - aSPrs->PrependObject(anIO); - GEOMBase_Helper::displayPreview(aSPrs, true, true); - } - } + Handle(AIS_AngleDimension) anIO = + new AIS_AngleDimension(anEdge1, anEdge2, aPlane, theAngle * M_PI / 180., + TCollection_ExtendedString(Angle_str.c_str())); + + anIO->SetArrowSize((theAngle * M_PI / 180) * (aLength/20)); + + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + int w = resMgr->integerValue("Geometry", "measures_line_width", 1); + Handle(Prs3d_AngleAspect) asp = new Prs3d_AngleAspect(); + asp->LineAspect()->SetWidth(w); + anIO->Attributes()->SetAngleAspect(asp); - myPrsType = TYPE_LENGTH; + return anIO; } //================================================================ diff --git a/src/EntityGUI/EntityGUI_3DSketcherDlg.h b/src/EntityGUI/EntityGUI_3DSketcherDlg.h index 8888cf065..893bbe83e 100755 --- a/src/EntityGUI/EntityGUI_3DSketcherDlg.h +++ b/src/EntityGUI/EntityGUI_3DSketcherDlg.h @@ -28,12 +28,15 @@ class QButtonGroup; class QDoubleSpinBox; class EntityGUI_3Spin; +class EntityGUI_Type; class EntityGUI_Angles; class EntityGUI_Controls; -class DlgRef_3Radio; class SOCC_Prs; +class gp_Dir; #include +#include +#include #ifndef COORD_MIN # define COORD_MIN -1e+15 @@ -52,11 +55,20 @@ class EntityGUI_3DSketcherDlg : public GEOMBase_Skeleton struct XYZ { - XYZ() { x = y = z = 0.0; command = params = ""; } + XYZ() { x = y = z = 0.0; command = params = ""; L=A=0; } double x, y, z; // for preview only + int L, A; // for preview only QString command; QString params; }; + + struct prsType + { + prsType(){L=A=0;} + int L; + int A; + }; + typedef QList XYZList; public: @@ -82,10 +94,30 @@ private: const int = -1, const int = -1); + Handle(AIS_LengthDimension) createAISLengthDimension(double theLength, + gp_Pnt P1, + gp_Pnt P2, + gp_Dir theNormal); + + Handle(AIS_AngleDimension) createAISAngleDimension(double theAngle, + gp_Pnt P0, + gp_Pnt P1, + gp_Pnt P2); + + void displayAngle(double theAngle, + gp_Pnt P0, + gp_Pnt P1, + gp_Pnt P2, + bool store = false); + + void displayLength(gp_Pnt P1, + gp_Pnt P2, + gp_Dir theNormal, + bool store = false); + void displayTrihedron( int ); - void displayAngle( double, double, double, int, bool store = false ); - void displayLength( double theLength = -1.0, bool store = false, int type = 1); + void displayDimensions(bool store = false); bool createShapes( GEOM::GEOM_Object_ptr, TopoDS_Shape&, @@ -95,27 +127,29 @@ private: XYZ getPenultimatePoint() const; XYZ getCurrentPoint() const; + gp_Dir getPresentationPlane() const; + std::string doubleToString( double ); - void removeLastIOFromPrs( int ); - void restoreLastIOToPrs( int ); + void removeLastIOFromPrs(); + void restoreLastIOToPrs(); private: XYZList myPointsList; XYZList myRedoList; AIS_ListOfInteractive myLengthIORedoList; AIS_ListOfInteractive myAngleIORedoList; - int myPrsType; - std::list myPrsTypeList; - std::list myPrsTypeRedoList; + prsType myPrsType; EntityGUI_3Spin* Group3Spin; EntityGUI_Angles* GroupAngles; EntityGUI_Controls* GroupControls; - DlgRef_3Radio* GroupType; - QButtonGroup* myTypeGroup; + EntityGUI_Type* GroupType; + QButtonGroup* myTypeGroup1; + QButtonGroup* myTypeGroup2; int myMode; + int myCoordType; int myOrientation; bool myOK; bool isLengthVisible; diff --git a/src/EntityGUI/EntityGUI_Angles_QTD.ui b/src/EntityGUI/EntityGUI_Angles_QTD.ui index 41199563b..ee719f2eb 100644 --- a/src/EntityGUI/EntityGUI_Angles_QTD.ui +++ b/src/EntityGUI/EntityGUI_Angles_QTD.ui @@ -6,8 +6,8 @@ 0 0 - 351 - 148 + 488 + 172 @@ -42,10 +42,10 @@ - + - + Create @@ -68,10 +68,10 @@ - + - + 0 @@ -95,7 +95,27 @@ - + + + + CheckBox + + + + + + + + + + CheckBox + + + + + + + @@ -120,16 +140,6 @@ - - - - CheckBox - - - - - - diff --git a/src/EntityGUI/EntityGUI_Type_QTD.ui b/src/EntityGUI/EntityGUI_Type_QTD.ui new file mode 100644 index 000000000..eaaf2c144 --- /dev/null +++ b/src/EntityGUI/EntityGUI_Type_QTD.ui @@ -0,0 +1,89 @@ + + + EntityGUI_Type_QTD + + + + 0 + 0 + 315 + 92 + + + + + + + + 0 + + + + + GroupBox + + + + + + RadioButton1 + + + false + + + + + + + RadioButton2 + + + false + + + + + + + + + + GroupBox + + + + + + RadioButton3 + + + false + + + + + + + RadioButton4 + + + false + + + + + + + + + + qPixmapFromMimeSource + + RadioButton1 + RadioButton2 + RadioButton3 + + + + diff --git a/src/EntityGUI/EntityGUI_Widgets.cxx b/src/EntityGUI/EntityGUI_Widgets.cxx index ddaa42e3d..0c59c7345 100644 --- a/src/EntityGUI/EntityGUI_Widgets.cxx +++ b/src/EntityGUI/EntityGUI_Widgets.cxx @@ -210,6 +210,20 @@ EntityGUI_Point::~EntityGUI_Point() { } +////////////////////////////////////////// +// EntityGUI_Type +////////////////////////////////////////// + +EntityGUI_Type::EntityGUI_Type( QWidget* parent, Qt::WindowFlags f ) +: QWidget( parent, f ) +{ + setupUi( this ); +} + +EntityGUI_Type::~EntityGUI_Type() +{ +} + ////////////////////////////////////////// // EntityGUI_Angles ////////////////////////////////////////// diff --git a/src/EntityGUI/EntityGUI_Widgets.h b/src/EntityGUI/EntityGUI_Widgets.h index 7e8f14e47..2668b91a8 100644 --- a/src/EntityGUI/EntityGUI_Widgets.h +++ b/src/EntityGUI/EntityGUI_Widgets.h @@ -222,6 +222,22 @@ public: QButtonGroup* ButtonGroup; }; +////////////////////////////////////////// +// EntityGUI_Type +////////////////////////////////////////// + +#include "ui_EntityGUI_Type_QTD.h" + +class EntityGUI_Type : public QWidget, + public Ui::EntityGUI_Type_QTD +{ + Q_OBJECT + +public: + EntityGUI_Type( QWidget* = 0, Qt::WindowFlags = 0 ); + ~EntityGUI_Type(); +}; + ////////////////////////////////////////// // EntityGUI_Angles ////////////////////////////////////////// diff --git a/src/EntityGUI/Makefile.am b/src/EntityGUI/Makefile.am index aece4f4a5..e6082ead5 100644 --- a/src/EntityGUI/Makefile.am +++ b/src/EntityGUI/Makefile.am @@ -85,6 +85,7 @@ UIC_FILES = \ ui_EntityGUI_Dir2_QTD.h \ ui_EntityGUI_Point_QTD.h \ ui_EntityGUI_Skeleton_QTD.h \ + ui_EntityGUI_Type_QTD.h \ ui_EntityGUI_Angles_QTD.h \ ui_EntityGUI_Controls_QTD.h diff --git a/src/GEOM/GEOM_Engine.cxx b/src/GEOM/GEOM_Engine.cxx index 32d3e97c2..988157174 100644 --- a/src/GEOM/GEOM_Engine.cxx +++ b/src/GEOM/GEOM_Engine.cxx @@ -1101,9 +1101,18 @@ bool ProcessFunction(Handle(GEOM_Function)& theFunction, else if (aCMDpref == "WW") { aNewDescr += "sk.close()"; } - else { - aNewDescr += "sk.addPointAnglesLength(\""; - aNewDescr += aCMDpref + "\", " + + else if (aCMDpref.Value(1) == 'O'){ + TCollection_AsciiString aCMDtrunc = aStrVals.Value(1); + aCMDtrunc.Trunc(3); + if (aCMDpref.Value(4) == 'C') + aNewDescr += "sk.addPointAngleHRad"; + else + aNewDescr += "sk.addPointAnglesRad"; + if (aCMDpref.Value(5) == 'A') + aNewDescr += "Absolute(\""; + else + aNewDescr += "Relative(\""; + aNewDescr += aCMDtrunc + "\", " + aStrVals.Value(2) + ", " + aStrVals.Value(3) + ", " + aStrVals.Value(4) + ")"; } } diff --git a/src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx b/src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx index d50aec791..3b2255a1f 100755 --- a/src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_3DSketcherDriver.cxx @@ -39,6 +39,8 @@ #include +#include + //======================================================================= //function : GetID //purpose : @@ -214,9 +216,19 @@ Standard_Integer GEOMImpl_3DSketcherDriver::Execute(TFunction_Logbook& log) cons if (aStrVals.Length() != 4) Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command."); + char type = aStrVals.Value(1).Value(4); + char mode = aStrVals.Value(1).Value(5); + double anAngle = aStrVals.Value(2).RealValue() * M_PI/180.0; - double anAngle2 = aStrVals.Value(3).RealValue() * M_PI/180.0; + double anAngle2 = aStrVals.Value(3).RealValue() * M_PI/180.0; double aLength = aStrVals.Value(4).RealValue(); + + double aHeight = aLength * sin(anAngle2); + if (type == 'C') + { + aHeight = aStrVals.Value(3).RealValue(); + anAngle2 = 0.0; + } double aProjectedLength = aLength * cos(anAngle2); @@ -224,21 +236,28 @@ Standard_Integer GEOMImpl_3DSketcherDriver::Execute(TFunction_Logbook& log) cons vp.SetX(aStrVals.Value(2).RealValue()); vp.SetY(aStrVals.Value(3).RealValue()); vp.SetZ(aStrVals.Value(4).RealValue()); - - if (aStrVals.Value(1) == "OXY") { - vp.SetX(p.X() + aProjectedLength * cos(anAngle)); - vp.SetY(p.Y() + aProjectedLength * sin(anAngle)); - vp.SetZ(p.Z() + aLength * sin(anAngle2)); + + gp_XYZ pref = gp::Origin().XYZ(); + if(mode == 'R') + pref = p; + + TCollection_AsciiString aTruncatedCommand = aStrVals.Value(1); + aTruncatedCommand.Trunc(3); + + if (aTruncatedCommand == "OXY") { + vp.SetX(pref.X() + aProjectedLength * cos(anAngle)); + vp.SetY(pref.Y() + aProjectedLength * sin(anAngle)); + vp.SetZ(pref.Z() + aHeight); } - else if (aStrVals.Value(1) == "OYZ") { - vp.SetX(p.X() + aLength * sin(anAngle2)); - vp.SetY(p.Y() + aProjectedLength * cos(anAngle)); - vp.SetZ(p.Z() + aProjectedLength * sin(anAngle)); + else if (aTruncatedCommand == "OYZ") { + vp.SetX(pref.X() + aHeight); + vp.SetY(pref.Y() + aProjectedLength * cos(anAngle)); + vp.SetZ(pref.Z() + aProjectedLength * sin(anAngle)); } - else if (aStrVals.Value(1) == "OXZ") { - vp.SetX(p.X() + aProjectedLength * cos(anAngle)); - vp.SetY(p.Y() + aLength * sin(anAngle2)); - vp.SetZ(p.Z() + aProjectedLength * sin(anAngle)); + else if (aTruncatedCommand == "OXZ") { + vp.SetX(pref.X() + aProjectedLength * cos(anAngle)); + vp.SetY(pref.Y() + aHeight); + vp.SetZ(pref.Z() + aProjectedLength * sin(anAngle)); } else Standard_ConstructionError::Raise("3D Sketcher error: Bad format of command."); @@ -295,7 +314,7 @@ Standard_Integer GEOMImpl_3DSketcherDriver::Execute(TFunction_Logbook& log) cons } else { } - + if (aShape.IsNull()) return 0; aFunction->SetValue(aShape); diff --git a/src/GEOM_SWIG/gsketcher.py b/src/GEOM_SWIG/gsketcher.py index 11cb0771c..f5ccc63bc 100644 --- a/src/GEOM_SWIG/gsketcher.py +++ b/src/GEOM_SWIG/gsketcher.py @@ -121,11 +121,14 @@ class Sketcher3D: ## Add one straight segment, defined by two angles and length. # If the first point of sketcher is not yet defined, the # origin (0, 0, 0) will become the first sketcher point. + # The radius and angles coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # # @param axes can be: "OXY", "OYZ" or "OXZ" # @param angle1 angle in a plane, defined by the \a axes # @param angle2 angle from the plane, defined by the \a axes # @param length length of the segment - def addPointAnglesLength (self, axes, angle1, angle2, length): + def addPointAnglesRadRelative (self, axes, angle1, angle2, length): """ Add one straight segment, defined by two angles and length. If the first point of sketcher is not yet defined, the @@ -139,10 +142,100 @@ class Sketcher3D: Example of usage: sk = geompy.Sketcher3D() - sk.addPointAnglesLength("OXY", 50, 0, 100) + sk.addPointAnglesRadRelative("OXY", 50, 0, 100) a3D_Sketcher_1 = sk.wire() """ - self.myCommand = self.myCommand + ":%s %s %s %s" % (axes, printVar(angle1), printVar(angle2), printVar(length)) + self.myCommand = self.myCommand + ":%s"%axes+"SR"+" %s %s %s" % (printVar(angle1), printVar(angle2), printVar(length)) + pass + + ## Add one straight segment, defined by two angles and radius. + # If the first point of sketcher is not yet defined, the + # origin (0, 0, 0) will become the first sketcher point. + # The radius and angles coordinates are defined + # in a coordinate system which origin is the global coordinate system origin + # + # @param axes can be: "OXY", "OYZ" or "OXZ" + # @param angle1 angle in a plane, defined by the \a axes + # @param angle2 angle from the plane, defined by the \a axes + # @param radius distance to the coordinate system origin + def addPointAnglesRadAbsolute (self, axes, angle1, angle2, radius): + """ + Add one straight segment, defined by two angles and length. + If the first point of sketcher is not yet defined, the + origin (0, 0, 0) will become the first sketcher point. + + Parameters: + axes can be: "OXY", "OYZ" or "OXZ" + angle1 angle in a plane, defined by the \a axes + angle2 angle from the plane, defined by the \a axes + radius distance to the coordinate system origin + + Example of usage: + sk = geompy.Sketcher3D() + sk.addPointAnglesRadAbsolute("OXY", 50, 0, 100) + a3D_Sketcher_1 = sk.wire() + """ + self.myCommand = self.myCommand + ":%s"%axes+"SA"+" %s %s %s" % (printVar(angle1), printVar(angle2), printVar(radius)) + pass + + ## Add one straight segment, defined by an angle, a height and a radius. + # If the first point of sketcher is not yet defined, the + # origin (0, 0, 0) will become the first sketcher point. + # The radius height and angle coordinates are defined + # in a local coordinate system which origin is the last point of the sketch + # + # @param axes can be: "OXY", "OYZ" or "OXZ" + # @param angle angle in a plane, defined by the \a axes + # @param height height from the plane, defined by the \a axes + # @param radius distance to the coordinate system origin + def addPointAngleHRadRelative (self, axes, angle, height, length): + """ + Add one straight segment, defined by two angles and length. + If the first point of sketcher is not yet defined, the + origin (0, 0, 0) will become the first sketcher point. + + Parameters: + axes can be: "OXY", "OYZ" or "OXZ" + angle1 angle in a plane, defined by the \a axes + height height from the plane, defined by the \a axes + radius distance to the coordinate system origin + + Example of usage: + sk = geompy.Sketcher3D() + sk.addPointAngleHRadRelative("OXY", 50, 40, 100) + a3D_Sketcher_1 = sk.wire() + """ + self.myCommand = self.myCommand + ":%s"%axes+"CR"+" %s %s %s" % (printVar(angle), printVar(height), printVar(length)) + pass + + ## Add one straight segment, defined by an angle, a height and a radius. + # If the first point of sketcher is not yet defined, the + # origin (0, 0, 0) will become the first sketcher point. + # The radius height and angle coordinates are defined + # in a coordinate system which origin is the global coordinate system origin + # + # @param axes can be: "OXY", "OYZ" or "OXZ" + # @param angle angle in a plane, defined by the \a axes + # @param height height from the plane, defined by the \a axes + # @param radius distance to the coordinate system origin + def addPointAngleHRadAbsolute (self, axes, angle, height, radius): + """ + Add one straight segment, defined by two angles and length. + If the first point of sketcher is not yet defined, the + origin (0, 0, 0) will become the first sketcher point. + + Parameters: + axes can be: "OXY", "OYZ" or "OXZ" + angle1 angle in a plane, defined by the \a axes + height height from the plane, defined by the \a axes + radius distance to the coordinate system origin + + Example of usage: + sk = geompy.Sketcher3D() + sk.addPointAngleHRadAbsolute("OXY", 50, 40, 100) + a3D_Sketcher_1 = sk.wire() + """ + self.myCommand = self.myCommand + ":%s"%axes+"CA"+" %s %s %s" % (printVar(angle), printVar(height), printVar(radius)) pass ## Set to close the wire -- 2.39.2