Part:Improve support for Links
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
|
||||
|
||||
#include "FeatureOffset.h"
|
||||
#include <App/Link.h>
|
||||
|
||||
|
||||
using namespace Part;
|
||||
@@ -131,8 +132,14 @@ short Offset2D::mustExecute() const
|
||||
App::DocumentObjectExecReturn *Offset2D::execute(void)
|
||||
{
|
||||
App::DocumentObject* source = Source.getValue();
|
||||
if (!(source && source->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())))
|
||||
|
||||
if (!source) {
|
||||
return new App::DocumentObjectExecReturn("No source shape linked.");
|
||||
}
|
||||
const TopoShape shape = Part::Feature::getTopoShape(source);
|
||||
if (shape.isNull()) {
|
||||
return new App::DocumentObjectExecReturn("No source shape linked.");
|
||||
}
|
||||
double offset = Value.getValue();
|
||||
short mode = (short)Mode.getValue();
|
||||
short join = (short)Join.getValue();
|
||||
@@ -140,7 +147,7 @@ App::DocumentObjectExecReturn *Offset2D::execute(void)
|
||||
bool inter = Intersection.getValue();
|
||||
if (mode == 2)
|
||||
return new App::DocumentObjectExecReturn("Mode 'Recto-Verso' is not supported for 2D offset.");
|
||||
const TopoShape& shape = static_cast<Part::Feature*>(source)->Shape.getShape();
|
||||
|
||||
this->Shape.setValue(shape.makeOffset2D(offset, join, fill, mode == 0, inter));
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
|
||||
|
||||
#include "PartFeatures.h"
|
||||
#include <App/Link.h>
|
||||
|
||||
|
||||
using namespace Part;
|
||||
@@ -82,20 +83,21 @@ App::DocumentObjectExecReturn* RuledSurface::getShape(const App::PropertyLinkSub
|
||||
TopoDS_Shape& shape) const
|
||||
{
|
||||
App::DocumentObject* obj = link.getValue();
|
||||
if (!(obj && obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())))
|
||||
const Part::TopoShape part = Part::Feature::getShape(obj, "", false, 0, 0, true, false);
|
||||
if (part.isNull()) {
|
||||
return new App::DocumentObjectExecReturn("No shape linked.");
|
||||
}
|
||||
|
||||
// if no explicit sub-shape is selected use the whole part
|
||||
const std::vector<std::string>& element = link.getSubValues();
|
||||
if (element.empty()) {
|
||||
shape = static_cast<Part::Feature*>(obj)->Shape.getValue();
|
||||
shape = part.getShape();
|
||||
return nullptr;
|
||||
}
|
||||
else if (element.size() != 1) {
|
||||
return new App::DocumentObjectExecReturn("Not exactly one sub-shape linked.");
|
||||
}
|
||||
|
||||
const Part::TopoShape& part = static_cast<Part::Feature*>(obj)->Shape.getValue();
|
||||
if (!part.getShape().IsNull()) {
|
||||
if (!element[0].empty()) {
|
||||
shape = part.getSubShape(element[0].c_str());
|
||||
|
||||
@@ -12,11 +12,17 @@ import FreeCAD as App
|
||||
def roundVector(v,dec):
|
||||
return str([round(v[0],dec), round(v[1],dec), round(v[2],dec)])
|
||||
|
||||
def buildShapeContent(obj, decimals=2, advancedShapeContent=True):
|
||||
def buildShapeContent(objArg, decimals=2, advancedShapeContent=True):
|
||||
linkName = ""
|
||||
if objArg.isDerivedFrom("App::Link"):
|
||||
obj = objArg.getLinkedObject()
|
||||
linkName = "<" + objArg.Name + "> "
|
||||
else:
|
||||
obj = objArg
|
||||
shp = obj.Shape
|
||||
typeStr = str(shp.ShapeType)
|
||||
lbl = '' if obj.Name == obj.Label else '(' + obj.Label + ')'
|
||||
result = obj.Name + lbl + '\n'
|
||||
result = linkName + obj.Name + lbl + '\n'
|
||||
result += 'Shape type: '+typeStr+'\n'
|
||||
result += 'Vertices: '+str(len(shp.Vertexes))+'\n'
|
||||
result += 'Edges: '+str(len(shp.Edges))+'\n'
|
||||
@@ -64,17 +70,17 @@ def buildShapeContent(obj, decimals=2, advancedShapeContent=True):
|
||||
result += str(p)+': '+roundVector(props[p],decimals) +'\n'
|
||||
else:
|
||||
result += str(p)+': '+str(props[p])+'\n'
|
||||
|
||||
if obj.getGlobalPlacement() != obj.Placement:
|
||||
rpl = obj.getGlobalPlacement() * obj.Placement.inverse()
|
||||
rot = rpl.Rotation
|
||||
if hasattr(shp, 'CenterOfMass'):
|
||||
result += 'Global CenterOfMass: '+roundVector(rpl.multVec(shp.CenterOfMass),decimals)+'\n'
|
||||
if hasattr(shp, 'PrincipalProperties'):
|
||||
props = shp.PrincipalProperties
|
||||
for p in props:
|
||||
if 'AxisOfInertia' in p:
|
||||
result += 'Global ' + str(p)+': '+roundVector(rot.multVec(props[p]),decimals) +'\n'
|
||||
else:
|
||||
result += 'Global Placement = Placement'
|
||||
if hasattr(obj,"getGlobalPlacement"):
|
||||
if obj.getGlobalPlacement() != obj.Placement:
|
||||
rpl = obj.getGlobalPlacement() * obj.Placement.inverse()
|
||||
rot = rpl.Rotation
|
||||
if hasattr(shp, 'CenterOfMass'):
|
||||
result += 'Global CenterOfMass: '+roundVector(rpl.multVec(shp.CenterOfMass),decimals)+'\n'
|
||||
if hasattr(shp, 'PrincipalProperties'):
|
||||
props = shp.PrincipalProperties
|
||||
for p in props:
|
||||
if 'AxisOfInertia' in p:
|
||||
result += 'Global ' + str(p)+': '+roundVector(rot.multVec(props[p]),decimals) +'\n'
|
||||
else:
|
||||
result += 'Global Placement = Placement'
|
||||
return result
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <App/Link.h>
|
||||
#include <Gui/Action.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
@@ -251,6 +252,38 @@ bool checkForSolids(const TopoDS_Shape& shape)
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
* returns vector of Part::TopoShapes from selected Part::Feature derived objects,
|
||||
* App::Links linked to Part::Features, or App::Part containers with visible Part::Features
|
||||
*/
|
||||
std::vector<Part::TopoShape> getShapesFromSelection()
|
||||
{
|
||||
std::vector<App::DocumentObject*> objs = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId());
|
||||
std::vector <Part::TopoShape> shapes;
|
||||
for (std::vector<App::DocumentObject*>::iterator it = objs.begin(); it != objs.end(); ++it) {
|
||||
Part::TopoShape shp = Part::Feature::getTopoShape(*it);
|
||||
if (!shp.isNull()){
|
||||
shapes.push_back(shp);
|
||||
}
|
||||
}
|
||||
return shapes;
|
||||
}
|
||||
/*
|
||||
* returns true if selected objects contain valid Part::TopoShapes.
|
||||
* Objects can be Part::Features, App::Links, or App::Parts
|
||||
*/
|
||||
bool hasShapesInSelection()
|
||||
{
|
||||
bool hasShapes = false;
|
||||
std::vector<App::DocumentObject*> docobjs = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId());
|
||||
for (std::vector<App::DocumentObject*>::iterator it = docobjs.begin(); it != docobjs.end(); ++it) {
|
||||
if (!Part::Feature::getTopoShape(*it).isNull()) {
|
||||
hasShapes = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return hasShapes;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -1005,7 +1038,7 @@ void CmdPartImport::activated(int iMsg)
|
||||
Gui::WaitCursor wc;
|
||||
App::Document* pDoc = getDocument();
|
||||
if (!pDoc) // no document
|
||||
return;
|
||||
return;
|
||||
|
||||
fn = Base::Tools::escapeEncodeFilename(fn);
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Import Part"));
|
||||
@@ -1067,7 +1100,7 @@ void CmdPartExport::activated(int iMsg)
|
||||
if (!fn.isEmpty()) {
|
||||
App::Document* pDoc = getDocument();
|
||||
if (!pDoc) // no document
|
||||
return;
|
||||
return;
|
||||
if (select == filter[1] ||
|
||||
select == filter[3]) {
|
||||
Gui::Application::Instance->exportTo((const char*)fn.toUtf8(),pDoc->getName(),"ImportGui");
|
||||
@@ -1270,7 +1303,7 @@ void CmdPartReverseShape::activated(int iMsg)
|
||||
bool CmdPartReverseShape::isActive(void)
|
||||
{
|
||||
return Gui::Selection().countObjectsOfType
|
||||
(Part::Feature::getClassTypeId()) > 0;
|
||||
(Part::Feature::getClassTypeId(), 0, 3) > 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -1518,11 +1551,10 @@ void CmdPartCrossSections::activated(int iMsg)
|
||||
Q_UNUSED(iMsg);
|
||||
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
|
||||
if (!dlg) {
|
||||
std::vector<App::DocumentObject*> obj = Gui::Selection().getObjectsOfType
|
||||
(Part::Feature::getClassTypeId());
|
||||
std::vector<Part::TopoShape> shapes = PartGui::getShapesFromSelection();
|
||||
Base::BoundBox3d bbox;
|
||||
for (std::vector<App::DocumentObject*>::iterator it = obj.begin(); it != obj.end(); ++it) {
|
||||
bbox.Add(static_cast<Part::Feature*>(*it)->Shape.getBoundingBox());
|
||||
for (std::vector<Part::TopoShape>::iterator it = shapes.begin(); it != shapes.end(); ++it) {
|
||||
bbox.Add((*it).getBoundBox());
|
||||
}
|
||||
dlg = new PartGui::TaskCrossSections(bbox);
|
||||
}
|
||||
@@ -1531,8 +1563,8 @@ void CmdPartCrossSections::activated(int iMsg)
|
||||
|
||||
bool CmdPartCrossSections::isActive(void)
|
||||
{
|
||||
return (Gui::Selection().countObjectsOfType(Part::Feature::getClassTypeId()) > 0 &&
|
||||
!Gui::Control().activeDialog());
|
||||
bool hasShapes = PartGui::hasShapesInSelection();
|
||||
return (hasShapes && !Gui::Control().activeDialog());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -1643,9 +1675,16 @@ CmdPartOffset::CmdPartOffset()
|
||||
void CmdPartOffset::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
auto shapes = getSelection().getObjectsOfType(Part::Feature::getClassTypeId(),nullptr,3);
|
||||
if(shapes.empty())
|
||||
std::vector<App::DocumentObject*> docobjs = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> shapes;
|
||||
for (std::vector<App::DocumentObject*>::iterator it = docobjs.begin(); it != docobjs.end(); ++it) {
|
||||
if (!Part::Feature::getTopoShape(*it).isNull()) {
|
||||
shapes.push_back(*it);
|
||||
}
|
||||
}
|
||||
if (shapes.size() != 1) {
|
||||
return;
|
||||
}
|
||||
App::DocumentObject* shape = shapes.front();
|
||||
std::string offset = getUniqueObjectName("Offset");
|
||||
|
||||
@@ -1668,9 +1707,15 @@ void CmdPartOffset::activated(int iMsg)
|
||||
|
||||
bool CmdPartOffset::isActive(void)
|
||||
{
|
||||
Base::Type partid = Base::Type::fromName("Part::Feature");
|
||||
bool objectsSelected = Gui::Selection().countObjectsOfType(partid,nullptr,3) == 1;
|
||||
return (objectsSelected && !Gui::Control().activeDialog());
|
||||
{
|
||||
bool hasShapes = PartGui::hasShapesInSelection();
|
||||
std::vector<App::DocumentObject*> docobjs = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId());
|
||||
return (hasShapes && !Gui::Control().activeDialog() && docobjs.size() == 1);
|
||||
}
|
||||
|
||||
// Base::Type partid = Base::Type::fromName("Part::Feature");
|
||||
// bool objectsSelected = Gui::Selection().countObjectsOfType(partid,0,3) == 1;
|
||||
// return (objectsSelected && !Gui::Control().activeDialog());
|
||||
}
|
||||
|
||||
|
||||
@@ -1695,9 +1740,17 @@ CmdPartOffset2D::CmdPartOffset2D()
|
||||
void CmdPartOffset2D::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
auto shapes = getSelection().getObjectsOfType(Part::Feature::getClassTypeId(),nullptr,3);
|
||||
if(shapes.empty())
|
||||
std::vector<App::DocumentObject*> docobjs = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> shapes;
|
||||
|
||||
for (std::vector<App::DocumentObject*>::iterator it = docobjs.begin(); it != docobjs.end(); ++it) {
|
||||
if (!Part::Feature::getTopoShape(*it).isNull()) {
|
||||
shapes.push_back(*it);
|
||||
}
|
||||
}
|
||||
if (shapes.size() != 1) {
|
||||
return;
|
||||
}
|
||||
App::DocumentObject* shape = shapes.front();
|
||||
std::string offset = getUniqueObjectName("Offset2D");
|
||||
|
||||
@@ -1720,9 +1773,9 @@ void CmdPartOffset2D::activated(int iMsg)
|
||||
|
||||
bool CmdPartOffset2D::isActive(void)
|
||||
{
|
||||
Base::Type partid = Base::Type::fromName("Part::Feature");
|
||||
bool objectsSelected = Gui::Selection().countObjectsOfType(partid,nullptr,3) == 1;
|
||||
return (objectsSelected && !Gui::Control().activeDialog());
|
||||
bool hasShapes = PartGui::hasShapesInSelection();
|
||||
std::vector<App::DocumentObject*> docobjs = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId());
|
||||
return (hasShapes && !Gui::Control().activeDialog() && docobjs.size() == 1);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -1813,11 +1866,10 @@ void CmdPartCompOffset::languageChange()
|
||||
|
||||
bool CmdPartCompOffset::isActive(void)
|
||||
{
|
||||
Base::Type partid = Base::Type::fromName("Part::Feature");
|
||||
bool objectsSelected = Gui::Selection().countObjectsOfType(partid,nullptr,3) == 1;
|
||||
return (objectsSelected && !Gui::Control().activeDialog());
|
||||
bool hasShapes = PartGui::hasShapesInSelection();
|
||||
std::vector<App::DocumentObject*> docobjs = Gui::Selection().getObjectsOfType(App::DocumentObject::getClassTypeId());
|
||||
return (hasShapes && !Gui::Control().activeDialog() && docobjs.size() == 1);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Part_Thickness
|
||||
//===========================================================================
|
||||
@@ -1839,31 +1891,48 @@ CmdPartThickness::CmdPartThickness()
|
||||
void CmdPartThickness::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
Gui::SelectionFilter faceFilter ("SELECT Part::Feature SUBELEMENT Face COUNT 1..");
|
||||
if (!faceFilter.match()) {
|
||||
QMessageBox::warning(Gui::getMainWindow(),
|
||||
QApplication::translate("CmdPartThickness", "Wrong selection"),
|
||||
QApplication::translate("CmdPartThickness", "Selected one or more faces of a shape"));
|
||||
return;
|
||||
const App::DocumentObject* obj = nullptr;
|
||||
std::string selection;
|
||||
const std::vector<Gui::SelectionObject> selobjs = Gui::Selection().getSelectionEx();
|
||||
std::vector<Part::TopoShape> subShapes;
|
||||
Part::TopoShape topoShape = Part::TopoShape();
|
||||
|
||||
bool ok = true;
|
||||
if (selobjs.size() == 1) {
|
||||
selection = selobjs[0].getAsPropertyLinkSubString();
|
||||
const std::vector<std::string>& subnames = selobjs[0].getSubNames();
|
||||
obj = selobjs[0].getObject();
|
||||
topoShape = Part::Feature::getTopoShape(obj);
|
||||
if (!topoShape.isNull()) {
|
||||
for (std::vector<std::string>::const_iterator it = subnames.begin(); it != subnames.end(); ++it) {
|
||||
subShapes.push_back(topoShape.getSubShape(subnames[0].c_str()));
|
||||
}
|
||||
for (std::vector<Part::TopoShape>::iterator it = subShapes.begin(); it != subShapes.end(); ++it) {
|
||||
TopoDS_Shape dsShape = (*it).getShape();
|
||||
if (dsShape.IsNull() || dsShape.ShapeType() != TopAbs_FACE) { //only face selection allowed
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
} else { //could be not a part::feature or app:link to non-part::feature or app::part without a visible part::feature
|
||||
ok = false;
|
||||
}
|
||||
|
||||
} else { //not just one object selected
|
||||
ok = false;
|
||||
}
|
||||
|
||||
// get the selected object
|
||||
const std::vector<Gui::SelectionObject>& result = faceFilter.Result[0];
|
||||
std::string selection = result.front().getAsPropertyLinkSubString();
|
||||
|
||||
const Part::Feature* shape = static_cast<const Part::Feature*>(result.front().getObject());
|
||||
if (shape->Shape.getValue().IsNull())
|
||||
return;
|
||||
int countSolids = 0;
|
||||
TopExp_Explorer xp;
|
||||
xp.Init(shape->Shape.getValue(),TopAbs_SOLID);
|
||||
for (;xp.More(); xp.Next()) {
|
||||
countSolids++;
|
||||
if (!topoShape.isNull()){
|
||||
xp.Init(topoShape.getShape(), TopAbs_SOLID);
|
||||
for (;xp.More(); xp.Next()) {
|
||||
countSolids++;
|
||||
}
|
||||
}
|
||||
if (countSolids != 1) {
|
||||
if (countSolids != 1 || !ok) {
|
||||
QMessageBox::warning(Gui::getMainWindow(),
|
||||
QApplication::translate("CmdPartThickness", "Wrong selection"),
|
||||
QApplication::translate("CmdPartThickness", "Selected shape is not a solid"));
|
||||
QApplication::translate("CmdPartThickness", "Wrong selection"),
|
||||
QApplication::translate("CmdPartThickness", "Selected shape is not a solid"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1874,22 +1943,24 @@ void CmdPartThickness::activated(int iMsg)
|
||||
doCommand(Doc,"App.ActiveDocument.%s.Faces = %s" ,thick.c_str(), selection.c_str());
|
||||
doCommand(Doc,"App.ActiveDocument.%s.Value = 1.0",thick.c_str());
|
||||
updateActive();
|
||||
if (isActiveObjectValid())
|
||||
doCommand(Gui,"Gui.ActiveDocument.hide(\"%s\")",shape->getNameInDocument());
|
||||
if (isActiveObjectValid()) {
|
||||
doCommand(App,"App.getDocument(\"%s\").getObject(\"%s\").ViewObject.Visibility = False",
|
||||
obj->getDocument()->getName(), obj->getNameInDocument());
|
||||
}
|
||||
doCommand(Gui,"Gui.ActiveDocument.setEdit('%s')",thick.c_str());
|
||||
|
||||
//commitCommand();
|
||||
adjustCameraPosition();
|
||||
|
||||
copyVisual(thick.c_str(), "ShapeColor", shape->getNameInDocument());
|
||||
copyVisual(thick.c_str(), "LineColor" , shape->getNameInDocument());
|
||||
copyVisual(thick.c_str(), "PointColor", shape->getNameInDocument());
|
||||
copyVisual(thick.c_str(), "ShapeColor", obj->getNameInDocument());
|
||||
copyVisual(thick.c_str(), "LineColor" , obj->getNameInDocument());
|
||||
copyVisual(thick.c_str(), "PointColor", obj->getNameInDocument());
|
||||
}
|
||||
|
||||
bool CmdPartThickness::isActive(void)
|
||||
{
|
||||
Base::Type partid = Base::Type::fromName("Part::Feature");
|
||||
bool objectsSelected = Gui::Selection().countObjectsOfType(partid) > 0;
|
||||
bool objectsSelected = Gui::Selection().countObjectsOfType(partid, 0, 3) > 0;
|
||||
return (objectsSelected && !Gui::Control().activeDialog());
|
||||
}
|
||||
|
||||
@@ -2014,92 +2085,83 @@ CmdPartRuledSurface::CmdPartRuledSurface()
|
||||
void CmdPartRuledSurface::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
bool ok = false;
|
||||
bool ok = true;
|
||||
TopoDS_Shape curve1, curve2;
|
||||
std::string link1, link2, obj1, obj2;
|
||||
Gui::SelectionFilter edgeFilter ("SELECT Part::Feature SUBELEMENT Edge COUNT 1..2");
|
||||
Gui::SelectionFilter wireFilter ("SELECT Part::Feature SUBELEMENT Wire COUNT 1..2");
|
||||
Gui::SelectionFilter partFilter ("SELECT Part::Feature COUNT 2");
|
||||
bool matchEdge = edgeFilter.match();
|
||||
bool matchWire = wireFilter.match();
|
||||
if (matchEdge || matchWire) {
|
||||
// get the selected object
|
||||
const std::vector<Gui::SelectionObject>& result = matchEdge
|
||||
? edgeFilter.Result[0] : wireFilter.Result[0];
|
||||
// two edges from one object
|
||||
if (result.size() == 1) {
|
||||
const Part::Feature* part = static_cast<const Part::Feature*>(result[0].getObject());
|
||||
const std::vector<std::string>& edges = result[0].getSubNames();
|
||||
if (edges.size() != 2) {
|
||||
ok = false;
|
||||
}
|
||||
else {
|
||||
ok = true;
|
||||
// get the selected sub-shapes
|
||||
const Part::TopoShape& shape = part->Shape.getValue();
|
||||
curve1 = shape.getSubShape(edges[0].c_str());
|
||||
curve2 = shape.getSubShape(edges[1].c_str());
|
||||
obj1 = result[0].getObject()->getNameInDocument();
|
||||
link1 = edges[0];
|
||||
obj2 = result[0].getObject()->getNameInDocument();
|
||||
link2 = edges[1];
|
||||
}
|
||||
}
|
||||
// two objects and one edge per object
|
||||
else if (result.size() == 2) {
|
||||
const Part::Feature* part1 = static_cast<const Part::Feature*>(result[0].getObject());
|
||||
const std::vector<std::string>& edges1 = result[0].getSubNames();
|
||||
const Part::Feature* part2 = static_cast<const Part::Feature*>(result[1].getObject());
|
||||
const std::vector<std::string>& edges2 = result[1].getSubNames();
|
||||
if (edges1.size() != 1 || edges2.size() != 1) {
|
||||
ok = false;
|
||||
}
|
||||
else {
|
||||
ok = true;
|
||||
const Part::TopoShape& shape1 = part1->Shape.getValue();
|
||||
curve1 = shape1.getSubShape(edges1[0].c_str());
|
||||
const Part::TopoShape& shape2 = part2->Shape.getValue();
|
||||
curve2 = shape2.getSubShape(edges2[0].c_str());
|
||||
obj1 = result[0].getObject()->getNameInDocument();
|
||||
link1 = edges1[0];
|
||||
obj2 = result[1].getObject()->getNameInDocument();
|
||||
link2 = edges2[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (partFilter.match()) {
|
||||
const std::vector<Gui::SelectionObject>& result = partFilter.Result[0];
|
||||
const Part::Feature* part1 = static_cast<const Part::Feature*>(result[0].getObject());
|
||||
const Part::Feature* part2 = static_cast<const Part::Feature*>(result[1].getObject());
|
||||
const Part::TopoShape& shape1 = part1->Shape.getValue();
|
||||
curve1 = shape1.getShape();
|
||||
const Part::TopoShape& shape2 = part2->Shape.getValue();
|
||||
curve2 = shape2.getShape();
|
||||
obj1 = part1->getNameInDocument();
|
||||
obj2 = part2->getNameInDocument();
|
||||
const std::vector<Gui::SelectionObject> selobjs = Gui::Selection().getSelectionEx();
|
||||
const App::DocumentObject* docobj1 = nullptr;
|
||||
const App::DocumentObject* docobj2 = nullptr;
|
||||
|
||||
if (selobjs.size() != 1 && selobjs.size() != 2) {
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if (ok && selobjs.size() <= 2) {
|
||||
if (selobjs.size() >= 1) {
|
||||
const std::vector<std::string>& subnames1= selobjs[0].getSubNames();
|
||||
docobj1 = selobjs[0].getObject();
|
||||
obj1 = docobj1->getNameInDocument();
|
||||
obj2 = obj1; //changed later if 2 objects were selected
|
||||
const Part::TopoShape& shape1 = Part::Feature::getTopoShape(docobj1);
|
||||
if (shape1.isNull()) {
|
||||
ok = false;
|
||||
}
|
||||
if (ok && subnames1.size() <= 2) {
|
||||
if (subnames1.size() >= 1) {
|
||||
curve1 = shape1.getSubShape(subnames1[0].c_str());
|
||||
link1 = subnames1[0];
|
||||
}
|
||||
if (subnames1.size() == 2) {
|
||||
curve2 = shape1.getSubShape(subnames1[1].c_str());
|
||||
link2 = subnames1[1];
|
||||
}
|
||||
if (subnames1.size() == 0) {
|
||||
curve1 = shape1.getShape();
|
||||
}
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
if (selobjs.size() == 2) {
|
||||
const std::vector<std::string>& subnames2 = selobjs[1].getSubNames();
|
||||
docobj2 = selobjs[1].getObject();
|
||||
obj2 = docobj2->getNameInDocument();
|
||||
|
||||
const Part::TopoShape& shape2 = Part::Feature::getTopoShape(docobj2);
|
||||
if (shape2.isNull()) {
|
||||
ok = false;
|
||||
}
|
||||
if (ok && subnames2.size() == 1) {
|
||||
curve2 = shape2.getSubShape(subnames2[0].c_str());
|
||||
link2 = subnames2[0];
|
||||
} else {
|
||||
if (subnames2.size() == 0) {
|
||||
curve2 = shape2.getShape();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!curve1.IsNull() && !curve2.IsNull()) {
|
||||
if (curve1.ShapeType() == TopAbs_EDGE &&
|
||||
curve2.ShapeType() == TopAbs_EDGE)
|
||||
ok = true;
|
||||
if (curve1.ShapeType() == TopAbs_WIRE &&
|
||||
curve2.ShapeType() == TopAbs_WIRE)
|
||||
if ((curve1.ShapeType() == TopAbs_EDGE || curve1.ShapeType() == TopAbs_WIRE)
|
||||
&& (curve2.ShapeType() == TopAbs_EDGE || curve2.ShapeType() == TopAbs_WIRE)) {
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!ok) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
|
||||
QObject::tr("You have to select either two edges or two wires."));
|
||||
QObject::tr("You have to select either two edges or two wires."));
|
||||
return;
|
||||
}
|
||||
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Create ruled surface"));
|
||||
doCommand(Doc, "FreeCAD.ActiveDocument.addObject('Part::RuledSurface', 'Ruled Surface')");
|
||||
doCommand(Doc, "FreeCAD.ActiveDocument.ActiveObject.Curve1=(FreeCAD.ActiveDocument.%s,['%s'])"
|
||||
,obj1.c_str(), link1.c_str());
|
||||
,obj1.c_str(), link1.c_str());
|
||||
doCommand(Doc, "FreeCAD.ActiveDocument.ActiveObject.Curve2=(FreeCAD.ActiveDocument.%s,['%s'])"
|
||||
,obj2.c_str(), link2.c_str());
|
||||
,obj2.c_str(), link2.c_str());
|
||||
commitCommand();
|
||||
updateActive();
|
||||
}
|
||||
@@ -2138,9 +2200,8 @@ void CmdCheckGeometry::activated(int iMsg)
|
||||
|
||||
bool CmdCheckGeometry::isActive(void)
|
||||
{
|
||||
Base::Type partid = Base::Type::fromName("Part::Feature");
|
||||
bool objectsSelected = Gui::Selection().countObjectsOfType(partid) > 0;
|
||||
return (hasActiveDocument() && !Gui::Control().activeDialog() && objectsSelected);
|
||||
bool hasShapes = PartGui::hasShapesInSelection();
|
||||
return (hasShapes && !Gui::Control().activeDialog());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -2502,8 +2563,7 @@ void CmdPartSectionCut::activated(int iMsg)
|
||||
|
||||
bool CmdPartSectionCut::isActive(void)
|
||||
{
|
||||
Gui::View3DInventor* view = dynamic_cast<Gui::View3DInventor*>(Gui::getMainWindow()->activeWindow());
|
||||
return view ? true : false;
|
||||
return hasActiveDocument();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
#include <App/Link.h>
|
||||
#include <Base/Sequencer.h>
|
||||
#include <Base/UnitsApi.h>
|
||||
|
||||
@@ -194,8 +195,14 @@ void CrossSections::accept()
|
||||
|
||||
void CrossSections::apply()
|
||||
{
|
||||
std::vector<App::DocumentObject*> obj = Gui::Selection().
|
||||
getObjectsOfType(Part::Feature::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> docobjs = Gui::Selection().
|
||||
getObjectsOfType(App::DocumentObject::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> obj;
|
||||
for (std::vector<App::DocumentObject*>::iterator it = docobjs.begin(); it != docobjs.end(); ++it){
|
||||
if (!Part::Feature::getTopoShape(*it).isNull()) {
|
||||
obj.push_back((*it)->getLinkedObject());
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<double> d;
|
||||
if (ui->sectionsBox->isChecked())
|
||||
|
||||
@@ -38,8 +38,9 @@
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Base/UnitsApi.h>
|
||||
#include <App/Link.h>
|
||||
#include <App/Part.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
@@ -69,16 +70,18 @@ public:
|
||||
bool allow(App::Document* /*pDoc*/, App::DocumentObject* pObj, const char* sSubName)
|
||||
{
|
||||
this->canSelect = false;
|
||||
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId()))
|
||||
return false;
|
||||
|
||||
if (!sSubName || sSubName[0] == '\0')
|
||||
return false;
|
||||
std::string element(sSubName);
|
||||
if (element.substr(0,4) != "Edge")
|
||||
return false;
|
||||
Part::Feature* fea = static_cast<Part::Feature*>(pObj);
|
||||
Part::TopoShape part = Part::Feature::getTopoShape(pObj);
|
||||
if (part.isNull()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
TopoDS_Shape sub = fea->Shape.getShape().getSubShape(sSubName);
|
||||
TopoDS_Shape sub = part.getSubShape(sSubName);
|
||||
if (!sub.IsNull() && sub.ShapeType() == TopAbs_EDGE) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(sub);
|
||||
BRepAdaptor_Curve adapt(edge);
|
||||
@@ -112,6 +115,8 @@ DlgExtrusion::DlgExtrusion(QWidget* parent, Qt::WindowFlags fl)
|
||||
|
||||
Gui::ItemViewSelection sel(ui->treeWidget);
|
||||
sel.applyFrom(Gui::Selection().getObjectsOfType(Part::Feature::getClassTypeId()));
|
||||
sel.applyFrom(Gui::Selection().getObjectsOfType(App::Link::getClassTypeId()));
|
||||
sel.applyFrom(Gui::Selection().getObjectsOfType(App::Part::getClassTypeId()));
|
||||
|
||||
this->on_DirMode_changed();
|
||||
ui->spinLenFwd->selectAll();
|
||||
@@ -317,27 +322,28 @@ void DlgExtrusion::fetchDir()
|
||||
void DlgExtrusion::autoSolid()
|
||||
{
|
||||
try{
|
||||
App::DocumentObject &dobj = this->getShapeToExtrude();
|
||||
if (dobj.isDerivedFrom(Part::Feature::getClassTypeId())){
|
||||
Part::Feature &feature = static_cast<Part::Feature&>(dobj);
|
||||
TopoDS_Shape sh = feature.Shape.getValue();
|
||||
if (sh.IsNull())
|
||||
App::DocumentObject* dobj = &this->getShapeToExtrude();
|
||||
Part::TopoShape shape = Part::Feature::getTopoShape(dobj);
|
||||
if (shape.isNull()) {
|
||||
return;
|
||||
}
|
||||
TopoDS_Shape sh = shape.getShape();
|
||||
if (sh.IsNull())
|
||||
return;
|
||||
ShapeExtend_Explorer xp;
|
||||
Handle(TopTools_HSequenceOfShape) leaves = xp.SeqFromCompound(sh, /*recursive= */Standard_True);
|
||||
int cntClosedWires = 0;
|
||||
for(int i = 0; i < leaves->Length(); i++){
|
||||
const TopoDS_Shape &leaf = leaves->Value(i+1);
|
||||
if (leaf.IsNull())
|
||||
return;
|
||||
ShapeExtend_Explorer xp;
|
||||
Handle(TopTools_HSequenceOfShape) leaves = xp.SeqFromCompound(sh, /*recursive= */Standard_True);
|
||||
int cntClosedWires = 0;
|
||||
for(int i = 0; i < leaves->Length(); i++){
|
||||
const TopoDS_Shape &leaf = leaves->Value(i+1);
|
||||
if (leaf.IsNull())
|
||||
return;
|
||||
if (leaf.ShapeType() == TopAbs_WIRE || leaf.ShapeType() == TopAbs_EDGE){
|
||||
if (BRep_Tool::IsClosed(leaf)){
|
||||
cntClosedWires++;
|
||||
}
|
||||
if (leaf.ShapeType() == TopAbs_WIRE || leaf.ShapeType() == TopAbs_EDGE){
|
||||
if (BRep_Tool::IsClosed(leaf)){
|
||||
cntClosedWires++;
|
||||
}
|
||||
}
|
||||
ui->chkSolid->setChecked( cntClosedWires == leaves->Length() );
|
||||
}
|
||||
ui->chkSolid->setChecked( cntClosedWires == leaves->Length() );
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
@@ -352,10 +358,15 @@ void DlgExtrusion::findShapes()
|
||||
this->document = activeDoc->getName();
|
||||
this->label = activeDoc->Label.getValue();
|
||||
|
||||
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType
|
||||
(Part::Feature::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType<App::DocumentObject>();
|
||||
|
||||
for (std::vector<App::DocumentObject*>::iterator it = objs.begin(); it!=objs.end(); ++it) {
|
||||
const TopoDS_Shape& shape = static_cast<Part::Feature*>(*it)->Shape.getValue();
|
||||
Part::TopoShape topoShape = Part::Feature::getTopoShape(*it);
|
||||
if (topoShape.isNull()) {
|
||||
continue;
|
||||
}
|
||||
TopoDS_Shape shape = topoShape.getShape();
|
||||
if (shape.IsNull()) continue;
|
||||
if (canExtrude(shape)) {
|
||||
QTreeWidgetItem* item = new QTreeWidgetItem(ui->treeWidget);
|
||||
item->setText(0, QString::fromUtf8((*it)->Label.getValue()));
|
||||
@@ -429,7 +440,7 @@ void DlgExtrusion::apply()
|
||||
for (App::DocumentObject* sourceObj: objects) {
|
||||
assert(sourceObj);
|
||||
|
||||
if (!sourceObj->isDerivedFrom(Part::Feature::getClassTypeId())){
|
||||
if (Part::Feature::getTopoShape(sourceObj).isNull()){
|
||||
FC_ERR("Object " << sourceObj->getFullName()
|
||||
<< " is not Part object (has no OCC shape). Can't extrude it.");
|
||||
continue;
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/Link.h>
|
||||
#include <App/Part.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
@@ -73,16 +75,18 @@ public:
|
||||
bool allow(App::Document* /*pDoc*/, App::DocumentObject*pObj, const char*sSubName)
|
||||
{
|
||||
this->canSelect = false;
|
||||
if (!pObj->isDerivedFrom(Part::Feature::getClassTypeId()))
|
||||
return false;
|
||||
|
||||
if (!sSubName || sSubName[0] == '\0')
|
||||
return false;
|
||||
std::string element(sSubName);
|
||||
if (element.substr(0,4) != "Edge")
|
||||
return false;
|
||||
Part::Feature* fea = static_cast<Part::Feature*>(pObj);
|
||||
Part::TopoShape part = Part::Feature::getTopoShape(pObj);
|
||||
if (part.isNull()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
TopoDS_Shape sub = fea->Shape.getShape().getSubShape(sSubName);
|
||||
TopoDS_Shape sub = part.getSubShape(sSubName);
|
||||
if (!sub.IsNull() && sub.ShapeType() == TopAbs_EDGE) {
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(sub);
|
||||
BRepAdaptor_Curve adapt(edge);
|
||||
@@ -127,6 +131,8 @@ DlgRevolution::DlgRevolution(QWidget* parent, Qt::WindowFlags fl)
|
||||
|
||||
Gui::ItemViewSelection sel(ui->treeWidget);
|
||||
sel.applyFrom(Gui::Selection().getObjectsOfType(Part::Feature::getClassTypeId()));
|
||||
sel.applyFrom(Gui::Selection().getObjectsOfType(App::Link::getClassTypeId()));
|
||||
sel.applyFrom(Gui::Selection().getObjectsOfType(App::Part::getClassTypeId()));
|
||||
|
||||
connect(ui->txtAxisLink, SIGNAL(textChanged(QString)), this, SLOT(on_txtAxisLink_textChanged(QString)));
|
||||
|
||||
@@ -327,10 +333,14 @@ void DlgRevolution::findShapes()
|
||||
return;
|
||||
Gui::Document* activeGui = Gui::Application::Instance->getDocument(activeDoc);
|
||||
|
||||
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType
|
||||
(Part::Feature::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType<App::DocumentObject>();
|
||||
|
||||
for (std::vector<App::DocumentObject*>::iterator it = objs.begin(); it!=objs.end(); ++it) {
|
||||
const TopoDS_Shape& shape = static_cast<Part::Feature*>(*it)->Shape.getValue();
|
||||
Part::TopoShape topoShape = Part::Feature::getTopoShape(*it);
|
||||
if (topoShape.isNull()) {
|
||||
continue;
|
||||
}
|
||||
TopoDS_Shape shape = topoShape.getShape();
|
||||
if (shape.IsNull()) continue;
|
||||
|
||||
TopExp_Explorer xp;
|
||||
@@ -521,9 +531,11 @@ void DlgRevolution::autoSolid()
|
||||
{
|
||||
try{
|
||||
App::DocumentObject &dobj = this->getShapeToRevolve();
|
||||
if (dobj.isDerivedFrom(Part::Feature::getClassTypeId())){
|
||||
Part::Feature &feature = static_cast<Part::Feature&>(dobj);
|
||||
TopoDS_Shape sh = feature.Shape.getValue();
|
||||
Part::TopoShape topoShape = Part::Feature::getTopoShape(&dobj);
|
||||
if (topoShape.isNull()) {
|
||||
return;
|
||||
} else {
|
||||
TopoDS_Shape sh = topoShape.getShape();
|
||||
if (sh.IsNull())
|
||||
return;
|
||||
ShapeExtend_Explorer xp;
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/Link.h>
|
||||
#include <App/Part.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
@@ -68,6 +70,8 @@ Mirroring::Mirroring(QWidget* parent)
|
||||
|
||||
Gui::ItemViewSelection sel(ui->shapes);
|
||||
sel.applyFrom(Gui::Selection().getObjectsOfType(Part::Feature::getClassTypeId()));
|
||||
sel.applyFrom(Gui::Selection().getObjectsOfType(App::Link::getClassTypeId()));
|
||||
sel.applyFrom(Gui::Selection().getObjectsOfType(App::Part::getClassTypeId()));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -89,19 +93,18 @@ void Mirroring::changeEvent(QEvent *e)
|
||||
void Mirroring::findShapes()
|
||||
{
|
||||
App::Document* activeDoc = App::GetApplication().getActiveDocument();
|
||||
if (!activeDoc)
|
||||
if (!activeDoc)
|
||||
return;
|
||||
Gui::Document* activeGui = Gui::Application::Instance->getDocument(activeDoc);
|
||||
if (!activeGui)
|
||||
if (!activeGui)
|
||||
return;
|
||||
|
||||
this->document = QString::fromLatin1(activeDoc->getName());
|
||||
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType
|
||||
(Part::Feature::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType<App::DocumentObject>();
|
||||
|
||||
for (std::vector<App::DocumentObject*>::iterator it = objs.begin(); it!=objs.end(); ++it) {
|
||||
const TopoDS_Shape& shape = static_cast<Part::Feature*>(*it)->Shape.getValue();
|
||||
if (!shape.IsNull()) {
|
||||
Part::TopoShape shape = Part::Feature::getTopoShape(*it);
|
||||
if (!shape.isNull()) {
|
||||
QString label = QString::fromUtf8((*it)->Label.getValue());
|
||||
QString name = QString::fromLatin1((*it)->getNameInDocument());
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/Link.h>
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
|
||||
@@ -102,10 +103,14 @@ void LoftWidget::findShapes()
|
||||
return;
|
||||
d->document = activeDoc->getName();
|
||||
|
||||
std::vector<Part::Feature*> objs = activeDoc->getObjectsOfType<Part::Feature>();
|
||||
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType<App::DocumentObject>();
|
||||
|
||||
for (std::vector<Part::Feature*>::iterator it = objs.begin(); it!=objs.end(); ++it) {
|
||||
TopoDS_Shape shape = (*it)->Shape.getValue();
|
||||
for (std::vector<App::DocumentObject*>::iterator it = objs.begin(); it!=objs.end(); ++it) {
|
||||
Part::TopoShape topoShape = Part::Feature::getTopoShape(*it);
|
||||
if (topoShape.isNull()) {
|
||||
continue;
|
||||
}
|
||||
TopoDS_Shape shape = topoShape.getShape();
|
||||
if (shape.IsNull()) continue;
|
||||
|
||||
// also allow compounds with a single face, wire or vertex or
|
||||
@@ -145,7 +150,6 @@ void LoftWidget::findShapes()
|
||||
shape.ShapeType() == TopAbs_VERTEX) {
|
||||
QString label = QString::fromUtf8((*it)->Label.getValue());
|
||||
QString name = QString::fromLatin1((*it)->getNameInDocument());
|
||||
|
||||
QTreeWidgetItem* child = new QTreeWidgetItem();
|
||||
child->setText(0, label);
|
||||
child->setToolTip(0, label);
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/Link.h>
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
|
||||
@@ -83,39 +84,41 @@ public:
|
||||
}
|
||||
bool allow(App::Document* /*pDoc*/, App::DocumentObject*pObj, const char*sSubName)
|
||||
{
|
||||
if (pObj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
|
||||
if (!sSubName || sSubName[0] == '\0') {
|
||||
// If selecting again the same edge the passed sub-element is empty. If the whole
|
||||
// shape is an edge or wire we can use it completely.
|
||||
const TopoDS_Shape& shape = static_cast<Part::Feature*>(pObj)->Shape.getValue();
|
||||
if (!shape.IsNull()) {
|
||||
// a single edge
|
||||
if (shape.ShapeType() == TopAbs_EDGE) {
|
||||
return true;
|
||||
}
|
||||
// a single wire
|
||||
if (shape.ShapeType() == TopAbs_WIRE) {
|
||||
return true;
|
||||
}
|
||||
// a compound of only edges or wires
|
||||
if (shape.ShapeType() == TopAbs_COMPOUND) {
|
||||
TopoDS_Iterator it(shape);
|
||||
for (; it.More(); it.Next()) {
|
||||
if (it.Value().IsNull())
|
||||
return false;
|
||||
if ((it.Value().ShapeType() != TopAbs_EDGE) &&
|
||||
if (!sSubName || sSubName[0] == '\0') {
|
||||
// If selecting again the same edge the passed sub-element is empty. If the whole
|
||||
// shape is an edge or wire we can use it completely.
|
||||
Part::TopoShape topoShape = Part::Feature::getTopoShape(pObj);
|
||||
if (topoShape.isNull()) {
|
||||
return false;
|
||||
}
|
||||
const TopoDS_Shape shape = topoShape.getShape();
|
||||
if (!shape.IsNull()) {
|
||||
// a single edge
|
||||
if (shape.ShapeType() == TopAbs_EDGE) {
|
||||
return true;
|
||||
}
|
||||
// a single wire
|
||||
if (shape.ShapeType() == TopAbs_WIRE) {
|
||||
return true;
|
||||
}
|
||||
// a compound of only edges or wires
|
||||
if (shape.ShapeType() == TopAbs_COMPOUND) {
|
||||
TopoDS_Iterator it(shape);
|
||||
for (; it.More(); it.Next()) {
|
||||
if (it.Value().IsNull())
|
||||
return false;
|
||||
if ((it.Value().ShapeType() != TopAbs_EDGE) &&
|
||||
(it.Value().ShapeType() != TopAbs_WIRE))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string element(sSubName);
|
||||
return element.substr(0,4) == "Edge";
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::string element(sSubName);
|
||||
return element.substr(0,4) == "Edge";
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -159,10 +162,14 @@ void SweepWidget::findShapes()
|
||||
return;
|
||||
d->document = activeDoc->getName();
|
||||
|
||||
std::vector<Part::Feature*> objs = activeDoc->getObjectsOfType<Part::Feature>();
|
||||
std::vector<App::DocumentObject*> objs = activeDoc->getObjectsOfType<App::DocumentObject>();
|
||||
|
||||
for (std::vector<Part::Feature*>::iterator it = objs.begin(); it!=objs.end(); ++it) {
|
||||
TopoDS_Shape shape = (*it)->Shape.getValue();
|
||||
for (std::vector<App::DocumentObject*>::iterator it = objs.begin(); it!=objs.end(); ++it) {
|
||||
Part::TopoShape topoShape = Part::Feature::getTopoShape(*it);
|
||||
if (topoShape.isNull()) {
|
||||
continue;
|
||||
}
|
||||
TopoDS_Shape shape = topoShape.getShape();
|
||||
if (shape.IsNull()) continue;
|
||||
|
||||
// also allow compounds with a single face, wire or vertex or
|
||||
@@ -217,13 +224,13 @@ void SweepWidget::findShapes()
|
||||
bool SweepWidget::isPathValid(const Gui::SelectionObject& sel) const
|
||||
{
|
||||
const App::DocumentObject* path = sel.getObject();
|
||||
if (!(path && path->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())))
|
||||
return false;
|
||||
const std::vector<std::string>& sub = sel.getSubNames();
|
||||
|
||||
|
||||
TopoDS_Shape pathShape;
|
||||
const Part::TopoShape& shape = static_cast<const Part::Feature*>(path)->Shape.getValue();
|
||||
const Part::TopoShape& shape = Part::Feature::getTopoShape(path);
|
||||
if (shape.isNull()){
|
||||
return false;
|
||||
}
|
||||
if (!sub.empty()) {
|
||||
try {
|
||||
BRepBuilderAPI_MakeWire mkWire;
|
||||
@@ -276,23 +283,38 @@ bool SweepWidget::accept()
|
||||
{
|
||||
if (d->ui.buttonPath->isChecked())
|
||||
return false;
|
||||
Gui::SelectionFilter edgeFilter ("SELECT Part::Feature SUBELEMENT Edge COUNT 1..");
|
||||
Gui::SelectionFilter partFilter ("SELECT Part::Feature COUNT 1");
|
||||
bool matchEdge = edgeFilter.match();
|
||||
bool matchPart = partFilter.match();
|
||||
if (!matchEdge && !matchPart) {
|
||||
QMessageBox::critical(this, tr("Sweep path"), tr("Select one or more connected edges you want to sweep along."));
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the selected object
|
||||
const App::DocumentObject* docobj = nullptr;
|
||||
std::string selection;
|
||||
const std::vector<Gui::SelectionObject> selobjs = Gui::Selection().getSelectionEx();
|
||||
std::vector<Part::TopoShape> subShapes;
|
||||
Part::TopoShape topoShape = Part::TopoShape();
|
||||
std::string spineObject, spineLabel;
|
||||
const std::vector<Gui::SelectionObject>& result = matchEdge
|
||||
? edgeFilter.Result[0] : partFilter.Result[0];
|
||||
selection = result.front().getAsPropertyLinkSubString();
|
||||
spineObject = result.front().getFeatName();
|
||||
spineLabel = result.front().getObject()->Label.getValue();
|
||||
|
||||
bool ok = true;
|
||||
if (selobjs.size() == 1) {
|
||||
selection = selobjs[0].getAsPropertyLinkSubString();
|
||||
const std::vector<std::string>& subnames = selobjs[0].getSubNames();
|
||||
docobj = selobjs[0].getObject();
|
||||
spineObject = selobjs[0].getFeatName();
|
||||
spineLabel = docobj->Label.getValue();
|
||||
topoShape = Part::Feature::getTopoShape(docobj);
|
||||
if (!topoShape.isNull()) {
|
||||
for (std::vector<std::string>::const_iterator it = subnames.begin(); it != subnames.end(); ++it) {
|
||||
subShapes.push_back(topoShape.getSubShape(subnames[0].c_str()));
|
||||
}
|
||||
for (std::vector<Part::TopoShape>::iterator it = subShapes.begin(); it != subShapes.end(); ++it) {
|
||||
TopoDS_Shape dsShape = (*it).getShape();
|
||||
if (dsShape.IsNull() || dsShape.ShapeType() != TopAbs_EDGE) { //only edge selection allowed
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
} else { //could be not a part::feature or app:link to non-part::feature or app::part without a visible part::feature
|
||||
ok = false;
|
||||
}
|
||||
|
||||
} else { //not just one object selected
|
||||
ok = false;
|
||||
}
|
||||
|
||||
QString list, solid, frenet;
|
||||
if (d->ui.checkSolid->isChecked())
|
||||
@@ -312,6 +334,10 @@ bool SweepWidget::accept()
|
||||
QMessageBox::critical(this, tr("Too few elements"), tr("At least one edge or wire is required."));
|
||||
return false;
|
||||
}
|
||||
if (!ok) {
|
||||
QMessageBox::critical(this, tr("Invalid selection"), tr("Select one or more edges from a single object."));
|
||||
return false;
|
||||
}
|
||||
for (int i=0; i<count; i++) {
|
||||
QTreeWidgetItem* child = d->ui.selector->selectedTreeWidget()->topLevelItem(i);
|
||||
QString name = child->data(0, Qt::UserRole).toString();
|
||||
|
||||
Reference in New Issue
Block a user