Files
create/src/Mod/Assembly/Gui/ViewProviderConstraint.cpp
jmaustpc 81e2e4714d Add new icons to Assembly work bench
Including new body icons for the treeview and
PartDesign create new body command.
Move all Assembly constrains icons into their
own sub directory of the icons directory
add "STEP, IGES or BREP" to the tool tip
of Assembly add existing Component command
2016-04-12 18:12:00 +02:00

447 lines
15 KiB
C++

/***************************************************************************
* Copyright (c) 2013 Stefan Tröger <stefantroeger@gmx.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#include "ViewProviderConstraint.h"
#include "TaskAssemblyConstraints.h"
#include "TaskDlgAssemblyConstraints.h"
#include "Mod/Assembly/App/Constraint.h"
#include "Mod/Assembly/App/ItemPart.h"
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
#include <App/Application.h>
#include <Gui/Control.h>
#include <BRep_Builder.hxx>
#include <Inventor/nodes/SoPolygonOffset.h>
#include <Inventor/nodes/SoGroup.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoShapeHints.h>
#include <Inventor/nodes/SoTransform.h>
#include <Inventor/nodes/SoSwitch.h>
using namespace AssemblyGui;
PROPERTY_SOURCE(AssemblyGui::ViewProviderConstraintInternal, PartGui::ViewProviderPart)
ViewProviderConstraintInternal::ViewProviderConstraintInternal()
{
//constraint entiti color
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
unsigned long scol = hGrp->GetUnsigned("ConstructionColor", 56319UL);
float r, g, b;
r = ((scol >> 24) & 0xff) / 255.0;
g = ((scol >> 16) & 0xff) / 255.0;
b = ((scol >> 8) & 0xff) / 255.0;
long unsigned ccol = hGrp->GetUnsigned("FullyConstrainedColor", 16711935UL);
float r2, g2, b2;
r2 = ((ccol >> 24) & 0xff) / 255.0;
g2 = ((ccol >> 16) & 0xff) / 255.0;
b2 = ((ccol >> 8) & 0xff) / 255.0;
int lwidth = hGrp->GetInt("DefaultShapeLineWidth", 2) + 1;
App::Material mat;
mat.ambientColor.set(0.2f, 0.2f, 0.2f);
mat.diffuseColor.set(r2, g2, b2);
mat.specularColor.set(0.0f, 0.0f, 0.0f);
mat.emissiveColor.set(0.0f, 0.0f, 0.0f);
mat.shininess = 1.0f;
mat.transparency = 0.5f;
LineMaterial.setValue(mat);
PointMaterial.setValue(mat);
LineColor.setValue(mat.diffuseColor);
PointColor.setValue(mat.diffuseColor);
mat.diffuseColor.set(r, g, b);
DiffuseColor.setValue(mat.diffuseColor);
LineWidth.setValue(lwidth);
PointSize.setValue(lwidth);
Transparency.setValue(50);
};
void ViewProviderConstraintInternal::updateVis(const TopoDS_Shape& shape)
{
updateVisual(shape);
};
void ViewProviderConstraintInternal::updatePlacement(const Base::Placement& p)
{
float q0 = (float)p.getRotation().getValue()[0];
float q1 = (float)p.getRotation().getValue()[1];
float q2 = (float)p.getRotation().getValue()[2];
float q3 = (float)p.getRotation().getValue()[3];
float px = (float)p.getPosition().x;
float py = (float)p.getPosition().y;
float pz = (float)p.getPosition().z;
pcTransform->rotation.setValue(q0, q1, q2, q3);
pcTransform->translation.setValue(px, py, pz);
pcTransform->center.setValue(0.0f, 0.0f, 0.0f);
}
void ViewProviderConstraintInternal::switch_node(bool onoff)
{
if(onoff)
pcModeSwitch->whichChild = 0;
else
pcModeSwitch->whichChild = -1;
}
void ViewProviderConstraint::setDisplayMode(const char* ModeName)
{
setDisplayMaskMode("Flat Lines");
}
std::vector<std::string> ViewProviderConstraint::getDisplayModes(void) const
{
std::vector<std::string> StrList;
// add your own mode
StrList.push_back("Flat Lines");
return StrList;
}
PROPERTY_SOURCE(AssemblyGui::ViewProviderConstraint, PartGui::ViewProviderPart)
ViewProviderConstraint::ViewProviderConstraint() : m_selected(false)
{
Selectable.setValue(false);
//constraint entiti color
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
unsigned long scol = hGrp->GetUnsigned("ConstructionColor", 56319UL);
float r, g, b;
r = ((scol >> 24) & 0xff) / 255.0;
g = ((scol >> 16) & 0xff) / 255.0;
b = ((scol >> 8) & 0xff) / 255.0;
long unsigned ccol = hGrp->GetUnsigned("FullyConstrainedColor", 16711935UL);
float r2, g2, b2;
r2 = ((ccol >> 24) & 0xff) / 255.0;
g2 = ((ccol >> 16) & 0xff) / 255.0;
b2 = ((ccol >> 8) & 0xff) / 255.0;
int lwidth = hGrp->GetInt("DefaultShapeLineWidth", 2) + 1;
App::Material mat;
mat.ambientColor.set(0.2f, 0.2f, 0.2f);
mat.diffuseColor.set(r2, g2, b2);
mat.specularColor.set(0.0f, 0.0f, 0.0f);
mat.emissiveColor.set(0.0f, 0.0f, 0.0f);
mat.shininess = 1.0f;
mat.transparency = 0.5f;
LineMaterial.setValue(mat);
PointMaterial.setValue(mat);
LineColor.setValue(mat.diffuseColor);
PointColor.setValue(mat.diffuseColor);
mat.diffuseColor.set(r, g, b);
DiffuseColor.setValue(mat.diffuseColor);
LineWidth.setValue(lwidth);
PointSize.setValue(lwidth);
Transparency.setValue(50);
}
bool ViewProviderConstraint::isShow() const
{
return Visibility.getValue();
}
void ViewProviderConstraint::attach(App::DocumentObject* pcFeat)
{
SoAnnotation* m_anno1 = new SoAnnotation;
SoAnnotation* m_anno2 = new SoAnnotation;
//call parent attach method for normal processing of one visual path
ViewProviderPart::attach(pcFeat);
//bring a annotation node before the normal view mode (others are not used)
m_anno1->addChild(pcModeSwitch->getChild(0));
pcModeSwitch->replaceChild(0, m_anno1);
//now also attach a second visual path to the root for our second constraint element
internal_vp.attach(pcFeat);
pcRoot->addChild(m_anno2);
m_anno2->addChild(internal_vp.getRoot());
internal_vp.setDisplayMM("Flat Lines");
}
void ViewProviderConstraint::update(const App::Property* prop) {
if(Visibility.getValue() && m_selected) {
draw();
}
ViewProviderPart::update(prop);
}
void ViewProviderConstraint::updateData(const App::Property* prop) {
//set the icon
int v = dynamic_cast<Assembly::Constraint*>(getObject())->Type.getValue();
if(v == 4)
sPixmap = "constraints/Assembly_ConstraintAlignment";
if(v == 3)
sPixmap = "constraints/Assembly_ConstraintAngle";
if(v == 5)
sPixmap = "constraints/Assembly_ConstraintCoincidence";
if(v == 1)
sPixmap = "constraints/Assembly_ConstraintDistance";
if(v == 0)
sPixmap = "constraints/Assembly_ConstraintLock";
if(v == 2)
sPixmap = "constraints/Assembly_ConstraintOrientation";
if(v==6)
sPixmap = "constraints/Assembly_ConstraintGeneral";
if(Visibility.getValue() && m_selected) {
draw();
}
Gui::ViewProviderGeometryObject::updateData(prop);
internal_vp.Gui::ViewProviderGeometryObject::updateData(prop);
}
void ViewProviderConstraint::onChanged(const App::Property* prop)
{
// parent expects the app object to be part::feature, but it isn't. so we have to avoid
// the visability prop as this results in accessing of the part::feature and would crash
if(prop == &Visibility) {
if(Visibility.getValue() && m_selected) {
internal_vp.show();
draw();
}
else
internal_vp.hide();
ViewProviderGeometryObject::onChanged(prop);
internal_vp.onChGO(prop);
}
else {
ViewProviderPart::onChanged(prop);
internal_vp.onChPa(prop);
}
}
void ViewProviderConstraint::draw()
{
TopoDS_Shape s1 = getConstraintShape(1);
updateVisual(s1);
TopoDS_Shape s2 = getConstraintShape(2);
internal_vp.updateVis(s2);
App::DocumentObject* obj1 = dynamic_cast<Assembly::Constraint*>(pcObject)->First.getValue();
if(!obj1)
return;
Assembly::ItemPart* part1 = static_cast<Assembly::ItemPart*>(obj1);
if(!part1)
return;
//the internal draw algorithm removes all locations. but we have this subshape extracted
//from a complex one, therefore it's translation is not respected in the parts rotation
//and if it gets cut away the geometry will be at wrong position
TopLoc_Location l1 = s1.Location();
gp_XYZ tr1 = l1.Transformation().TranslationPart();
Base::Placement p1(Base::Vector3d(tr1.X(), tr1.Y(), tr1.Z()), Base::Rotation());
upstream_placement(p1, part1);
//p1 = part1->m_part->getGlobal<Base::Placement>() * p1;
float q0 = (float)p1.getRotation().getValue()[0];
float q1 = (float)p1.getRotation().getValue()[1];
float q2 = (float)p1.getRotation().getValue()[2];
float q3 = (float)p1.getRotation().getValue()[3];
float px = (float)p1.getPosition().x;
float py = (float)p1.getPosition().y;
float pz = (float)p1.getPosition().z;
pcTransform->rotation.setValue(q0, q1, q2, q3);
pcTransform->translation.setValue(px, py, pz);
pcTransform->center.setValue(0.0f, 0.0f, 0.0f);
//Second part
//***********
App::DocumentObject* obj2 = dynamic_cast<Assembly::Constraint*>(pcObject)->Second.getValue();
if(!obj2)
return;
//here it's a bit more involved, as the coind tree structure let's the first transform node
//transform the second part too.
Assembly::ItemPart* part2 = static_cast<Assembly::ItemPart*>(obj2);
if(!part2)
return;
//the internal draw algorithm removes all locations. but we have this subshape extracted
//from a complex one, therefore it's shape internal translation is not respected in the parts rotation
//and if it gets cut away the geometry will be at wrong position
TopLoc_Location l2 = s2.Location();
gp_XYZ tr2 = l2.Transformation().TranslationPart();
Base::Placement p2(Base::Vector3d(tr2.X(), tr2.Y(), tr2.Z()), Base::Rotation());
upstream_placement(p2, part2);
p2 = p1.inverse()*p2;
//p2 = p1.inverse() * (part2->m_part->getGlobal<Base::Placement>() * p2);
internal_vp.updatePlacement(p2);
}
void ViewProviderConstraint::upstream_placement(Base::Placement& p, Assembly::Item* item) {
//successive transformation for this item
p = item->Placement.getValue() * p;
typedef std::vector<App::DocumentObject*>::const_iterator iter;
//get all links to this item and see if we have more ItemAssemblys
const std::vector<App::DocumentObject*>& vector = item->getInList();
for(iter it=vector.begin(); it != vector.end(); it++) {
if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) {
upstream_placement(p, static_cast<Assembly::ItemAssembly*>(*it));
return;
}
};
};
void ViewProviderConstraint::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if(Gui::Selection().isSelected(pcObject) && Visibility.getValue()) {
m_selected = true;
internal_vp.switch_node(true);
pcModeSwitch->whichChild = 0;
draw();
}
else if(!isEditing()) {
internal_vp.switch_node(false);
pcModeSwitch->whichChild = -1;
m_selected = false;
}
}
TopoDS_Shape ViewProviderConstraint::getConstraintShape(int link)
{
if(link == 1) {
//subshape of first link
//**********************
App::DocumentObject* obj1 = dynamic_cast<Assembly::Constraint*>(pcObject)->First.getValue();
if(!obj1)
return TopoDS_Shape();
Assembly::ItemPart* part1 = static_cast<Assembly::ItemPart*>(obj1);
if(!part1)
return TopoDS_Shape();
Part::TopoShape ts;
App::DocumentObject* feature1 = part1->Model.getValue();
if(feature1->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
ts = static_cast<Part::Feature*>(feature1)->Shape.getShape();
}
else
return TopoDS_Shape();
TopoDS_Shape s1 = ts.getSubShape(dynamic_cast<Assembly::Constraint*>(pcObject)->First.getSubValues()[0].c_str());
return s1;
}
else {
//subshape of second link
//**********************
App::DocumentObject* obj2 = dynamic_cast<Assembly::Constraint*>(pcObject)->Second.getValue();
if(!obj2)
return TopoDS_Shape();
Assembly::ItemPart* part2 = static_cast<Assembly::ItemPart*>(obj2);
if(!part2)
return TopoDS_Shape();
Part::TopoShape ts2;
App::DocumentObject* feature2 = part2->Model.getValue();
if(feature2->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
ts2 = static_cast<Part::Feature*>(feature2)->Shape.getShape();
}
else
return TopoDS_Shape();
TopoDS_Shape s2 = ts2.getSubShape(dynamic_cast<Assembly::Constraint*>(pcObject)->Second.getSubValues()[0].c_str());
return s2;
};
}
void ViewProviderConstraint::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
ViewProviderDocumentObject::setupContextMenu(menu, receiver, member);
}
bool ViewProviderConstraint::setEdit(int ModNum)
{
// When double-clicking on the item for this sketch the
// object unsets and sets its edit mode without closing
// the task panel
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
TaskDlgAssemblyConstraints* ConstraintsDlg = qobject_cast<TaskDlgAssemblyConstraints*>(dlg);
// start the edit dialog
if(ConstraintsDlg)
Gui::Control().showDialog(ConstraintsDlg);
else
Gui::Control().showDialog(new TaskDlgAssemblyConstraints(this));
//show the constraint geometries
internal_vp.switch_node(true);
pcModeSwitch->whichChild = 0;
draw();
return true;
}
void ViewProviderConstraint::unsetEdit(int ModNum)
{
if(!Gui::Selection().isSelected(pcObject) || !Visibility.getValue()) {
internal_vp.switch_node(false);
pcModeSwitch->whichChild = -1;
m_selected = false;
}
}