Path changes
* Relaxed valid base shape requirement, as long as it can return a shape using part.getShape() * Improve ViewProviderPath performance by sharing the same selection observer * Relocate libarea binary installation
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
#include <Mod/Part/App/OCCError.h>
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
#include <Mod/Part/App/TopoShapePy.h>
|
||||
#include <Mod/Part/App/PartPyCXX.h>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
@@ -94,10 +95,6 @@
|
||||
PyErr_SetString(Base::BaseExceptionFreeCADError,e); \
|
||||
} throw Py::Exception();
|
||||
|
||||
namespace Part {
|
||||
extern PartExport Py::Object shape2pyshape(const TopoDS_Shape &shape);
|
||||
}
|
||||
|
||||
namespace Path {
|
||||
class Module : public Py::ExtensionModule<Module>
|
||||
{
|
||||
|
||||
@@ -35,13 +35,10 @@
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
#include <Mod/Part/App/PartPyCXX.h>
|
||||
#include "Path.h"
|
||||
#include "AreaParams.h"
|
||||
|
||||
namespace Part {
|
||||
extern PartExport Py::Object shape2pyshape(const TopoDS_Shape &shape);
|
||||
}
|
||||
|
||||
class CArea;
|
||||
class CCurve;
|
||||
class Bnd_Box;
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
# include <QFile>
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
|
||||
#include "ViewProviderPath.h"
|
||||
|
||||
#include <Mod/Path/App/FeaturePath.h>
|
||||
@@ -53,6 +55,7 @@
|
||||
#include <Base/Stream.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Parameter.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/SoFCBoundingBox.h>
|
||||
#include <Gui/SoAxisCrossKit.h>
|
||||
@@ -75,6 +78,72 @@ using namespace PathGui;
|
||||
using namespace Path;
|
||||
using namespace PartGui;
|
||||
|
||||
namespace PathGui {
|
||||
|
||||
class PathSelectionObserver: public Gui::SelectionObserver {
|
||||
public:
|
||||
static void init() {
|
||||
static PathSelectionObserver *instance;
|
||||
if(!instance)
|
||||
instance = new PathSelectionObserver();
|
||||
}
|
||||
|
||||
void setArrow(SoSwitch *pcSwitch=0) {
|
||||
if(pcSwitch==pcLastArrowSwitch)
|
||||
return;
|
||||
if(pcLastArrowSwitch) {
|
||||
pcLastArrowSwitch->whichChild = -1;
|
||||
pcLastArrowSwitch->unref();
|
||||
pcLastArrowSwitch = 0;
|
||||
}
|
||||
if(pcSwitch) {
|
||||
pcSwitch->ref();
|
||||
pcSwitch->whichChild = 0;
|
||||
pcLastArrowSwitch = pcSwitch;
|
||||
}
|
||||
}
|
||||
|
||||
void onSelectionChanged(const Gui::SelectionChanges& msg) {
|
||||
if(msg.Type == Gui::SelectionChanges::RmvPreselect) {
|
||||
setArrow();
|
||||
return;
|
||||
}
|
||||
if((msg.Type!=Gui::SelectionChanges::SetPreselect
|
||||
&& msg.Type!=Gui::SelectionChanges::MovePreselect)
|
||||
|| !msg.pOriginalMsg || !msg.pSubObject || !msg.pParentObject)
|
||||
return;
|
||||
Base::Matrix4D linkMat;
|
||||
auto sobj = msg.pSubObject->getLinkedObject(true,&linkMat,false);
|
||||
auto vp = Base::freecad_dynamic_cast<ViewProviderPath>(
|
||||
Application::Instance->getViewProvider(sobj));
|
||||
if(!vp) {
|
||||
setArrow();
|
||||
return;
|
||||
}
|
||||
|
||||
if(vp->pt0Index >= 0) {
|
||||
Base::Matrix4D mat;
|
||||
msg.pParentObject->getSubObject(msg.pSubName,0,&mat);
|
||||
mat *= linkMat;
|
||||
mat.inverse();
|
||||
Base::Vector3d pt = mat*Base::Vector3d(msg.x,msg.y,msg.z);
|
||||
const SbVec3f &ptTo = *vp->pcLineCoords->point.getValues(vp->pt0Index);
|
||||
SbVec3f ptFrom(pt.x,pt.y,pt.z);
|
||||
if(ptFrom != ptTo) {
|
||||
vp->pcArrowTransform->pointAt(ptFrom,ptTo);
|
||||
setArrow(vp->pcArrowSwitch);
|
||||
return;
|
||||
}
|
||||
}
|
||||
setArrow();
|
||||
}
|
||||
|
||||
SoSwitch *pcLastArrowSwitch = 0;
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PROPERTY_SOURCE(PathGui::ViewProviderPath, Gui::ViewProviderGeometryObject)
|
||||
|
||||
ViewProviderPath::ViewProviderPath()
|
||||
@@ -171,6 +240,8 @@ ViewProviderPath::ViewProviderPath()
|
||||
SelectionStyle.setEnums(SelectionStyleEnum);
|
||||
unsigned long sstyle = hGrp->GetInt("DefaultSelectionStyle",0);
|
||||
SelectionStyle.setValue(sstyle);
|
||||
|
||||
PathSelectionObserver::init();
|
||||
}
|
||||
|
||||
ViewProviderPath::~ViewProviderPath()
|
||||
@@ -249,7 +320,7 @@ std::string ViewProviderPath::getElement(const SoDetail* detail) const
|
||||
pt0Index = line_detail->getPoint0()->getCoordinateIndex();
|
||||
if(pt0Index<0 || pt0Index>=pcLineCoords->point.getNum())
|
||||
pt0Index = -1;
|
||||
return str.str();
|
||||
return boost::replace_all_copy(str.str(),".",",");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -272,31 +343,6 @@ SoDetail* ViewProviderPath::getDetail(const char* subelement) const
|
||||
return detail;
|
||||
}
|
||||
|
||||
void ViewProviderPath::onSelectionChanged(const Gui::SelectionChanges& msg) {
|
||||
if(msg.Type == Gui::SelectionChanges::SetPreselect && msg.pSubName &&
|
||||
pt0Index >= 0 && getObject() && getObject()->getDocument())
|
||||
{
|
||||
const char *docName = getObject()->getDocument()->getName();
|
||||
const char *objName = getObject()->getNameInDocument();
|
||||
if(docName && objName &&
|
||||
strcmp(msg.pDocName,docName)==0 &&
|
||||
strcmp(msg.pObjectName,objName)==0)
|
||||
{
|
||||
Path::Feature* pcPathObj = static_cast<Path::Feature*>(pcObject);
|
||||
Base::Vector3d pt = pcPathObj->Placement.getValue().inverse().toMatrix()*
|
||||
Base::Vector3d(msg.x,msg.y,msg.z);
|
||||
const SbVec3f &ptTo = *pcLineCoords->point.getValues(pt0Index);
|
||||
SbVec3f ptFrom(pt.x,pt.y,pt.z);
|
||||
if(ptFrom != ptTo) {
|
||||
pcArrowTransform->pointAt(ptFrom,ptTo);
|
||||
pcArrowSwitch->whichChild = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
pcArrowSwitch->whichChild = -1;
|
||||
}
|
||||
|
||||
void ViewProviderPath::onChanged(const App::Property* prop)
|
||||
{
|
||||
if(blockPropertyChange) return;
|
||||
|
||||
@@ -42,8 +42,9 @@ class SoSwitch;
|
||||
namespace PathGui
|
||||
{
|
||||
|
||||
class PathSelectionObserver;
|
||||
|
||||
class PathGuiExport ViewProviderPath : public Gui::ViewProviderGeometryObject
|
||||
, public Gui::SelectionObserver
|
||||
{
|
||||
PROPERTY_HEADER(PathGui::ViewProviderPath);
|
||||
typedef ViewProviderGeometryObject inherited;
|
||||
@@ -78,14 +79,14 @@ public:
|
||||
virtual std::string getElement(const SoDetail *) const;
|
||||
SoDetail* getDetail(const char* subelement) const;
|
||||
|
||||
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
|
||||
|
||||
void updateShowConstraints();
|
||||
void updateVisual(bool rebuild = false);
|
||||
void hideSelection();
|
||||
|
||||
virtual void showBoundingBox(bool show);
|
||||
|
||||
friend class PathSelectionObserver;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void onChanged(const App::Property* prop);
|
||||
|
||||
@@ -104,15 +104,18 @@ class _CommandSelectLoop:
|
||||
FreeCADGui.Selection.addSelection(obj, "Edge" + str(elist.index(e) + 1))
|
||||
|
||||
def formsPartOfALoop(self, obj, sub, names):
|
||||
if names[0][0:4] != 'Edge':
|
||||
if names[0][0:4] == 'Face' and horizontalFaceLoop(obj, sub, names):
|
||||
try:
|
||||
if names[0][0:4] != 'Edge':
|
||||
if names[0][0:4] == 'Face' and horizontalFaceLoop(obj, sub, names):
|
||||
return True
|
||||
return False
|
||||
if len(names) == 1 and horizontalEdgeLoop(obj, sub):
|
||||
return True
|
||||
return False
|
||||
if len(names) == 1 and horizontalEdgeLoop(obj, sub):
|
||||
if len(names) == 1 or names[1][0:4] != 'Edge':
|
||||
return False
|
||||
return True
|
||||
if len(names) == 1 or names[1][0:4] != 'Edge':
|
||||
except Exception:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
if FreeCAD.GuiUp:
|
||||
|
||||
@@ -53,31 +53,20 @@ def isValidBaseObject(obj):
|
||||
# Can't link to anything inside a geo feature group anymore
|
||||
PathLog.debug("%s is inside a geo feature group" % obj.Label)
|
||||
return False
|
||||
if hasattr(obj, 'TypeId') and 'App::Part' == obj.TypeId:
|
||||
return obj.Group and any(hasattr(o, 'Shape') for o in obj.Group)
|
||||
if not hasattr(obj, 'Shape'):
|
||||
PathLog.debug("%s has no shape" % obj.Label)
|
||||
return False
|
||||
if obj.TypeId in NotValidBaseTypeIds:
|
||||
PathLog.debug("%s is blacklisted (%s)" % (obj.Label, obj.TypeId))
|
||||
return False
|
||||
if hasattr(obj, 'Sheets') or hasattr(obj, 'TagText'): # Arch.Panels and Arch.PanelCut
|
||||
PathLog.debug("%s is not an Arch.Panel" % (obj.Label))
|
||||
return False
|
||||
return True
|
||||
import Part
|
||||
return not Part.getShape(obj).isNull()
|
||||
|
||||
def isSolid(obj):
|
||||
'''isSolid(obj) ... return True if the object is a valid solid.'''
|
||||
if hasattr(obj, 'Tip'):
|
||||
return isSolid(obj.Tip)
|
||||
if hasattr(obj, 'Shape'):
|
||||
if obj.Shape.Volume > 0.0 and obj.Shape.isClosed():
|
||||
return True
|
||||
if hasattr(obj, 'TypeId') and 'App::Part' == obj.TypeId:
|
||||
if not obj.Group or any(hasattr(o, 'Shape') and not isSolid(o) for o in obj.Group):
|
||||
return False
|
||||
return True
|
||||
return False
|
||||
import Part
|
||||
shape = Part.getShape(obj)
|
||||
return not shape.isNull() and shape.Volume and shape.isClosed()
|
||||
|
||||
def toolControllerForOp(op):
|
||||
'''toolControllerForOp(op) ... return the tool controller used by the op.
|
||||
|
||||
@@ -98,7 +98,7 @@ add_library(
|
||||
|
||||
add_library(
|
||||
area
|
||||
MODULE
|
||||
SHARED
|
||||
${PYAREA_SRC}
|
||||
)
|
||||
|
||||
@@ -151,7 +151,7 @@ else(MSVC)
|
||||
endif(MSVC)
|
||||
|
||||
target_link_libraries(area-native ${area_native_LIBS})
|
||||
SET_BIN_DIR(area-native area-native)
|
||||
SET_BIN_DIR(area-native area-native /Mod/Path)
|
||||
|
||||
target_link_libraries(area area-native ${area_LIBS} ${area_native_LIBS})
|
||||
|
||||
@@ -161,7 +161,7 @@ if(NOT BUILD_DYNAMIC_LINK_PYTHON AND CMAKE_COMPILER_IS_CLANGXX)
|
||||
target_link_libraries(area "-Wl,-undefined,dynamic_lookup")
|
||||
endif()
|
||||
|
||||
SET_BIN_DIR(area area)
|
||||
SET_BIN_DIR(area area /Mod/Path)
|
||||
SET_PYTHON_PREFIX_SUFFIX(area)
|
||||
|
||||
# this figures out where to install the Python modules
|
||||
@@ -176,12 +176,11 @@ message(STATUS "area module (for Path Workbench) will be installed to: " ${CMAKE
|
||||
if(WIN32)
|
||||
set_target_properties(area-native PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||
INSTALL(TARGETS area-native
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
else(WIN32)
|
||||
INSTALL(TARGETS area-native
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
endif(WIN32)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user