Assembly: Introduce 'Exploded Views'
This commit is contained in:
committed by
Yorik van Havre
parent
6a834422e7
commit
687843ff41
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "AssemblyObject.h"
|
||||
#include "JointGroup.h"
|
||||
#include "ViewGroup.h"
|
||||
|
||||
|
||||
namespace Assembly
|
||||
@@ -58,6 +59,7 @@ PyMOD_INIT_FUNC(AssemblyApp)
|
||||
|
||||
Assembly::AssemblyObject ::init();
|
||||
Assembly::JointGroup ::init();
|
||||
Assembly::ViewGroup ::init();
|
||||
|
||||
PyMOD_Return(mod);
|
||||
}
|
||||
|
||||
@@ -19,12 +19,15 @@ set(Assembly_LIBS
|
||||
|
||||
generate_from_xml(AssemblyObjectPy)
|
||||
generate_from_xml(JointGroupPy)
|
||||
generate_from_xml(ViewGroupPy)
|
||||
|
||||
SET(Python_SRCS
|
||||
AssemblyObjectPy.xml
|
||||
AssemblyObjectPyImp.cpp
|
||||
JointGroupPy.xml
|
||||
JointGroupPyImp.cpp
|
||||
ViewGroupPy.xml
|
||||
ViewGroupPyImp.cpp
|
||||
)
|
||||
SOURCE_GROUP("Python" FILES ${Python_SRCS})
|
||||
|
||||
@@ -41,6 +44,8 @@ SET(Assembly_SRCS
|
||||
AssemblyObject.h
|
||||
JointGroup.cpp
|
||||
JointGroup.h
|
||||
ViewGroup.cpp
|
||||
ViewGroup.h
|
||||
${Module_SRCS}
|
||||
${Python_SRCS}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <[email protected]> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <App/FeaturePythonPyImp.h>
|
||||
#include <App/PropertyPythonObject.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Tools.h>
|
||||
|
||||
#include "ViewGroup.h"
|
||||
#include "ViewGroupPy.h"
|
||||
|
||||
using namespace Assembly;
|
||||
|
||||
|
||||
PROPERTY_SOURCE(Assembly::ViewGroup, App::DocumentObjectGroup)
|
||||
|
||||
ViewGroup::ViewGroup()
|
||||
{}
|
||||
|
||||
ViewGroup::~ViewGroup() = default;
|
||||
|
||||
PyObject* ViewGroup::getPyObject()
|
||||
{
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new ViewGroupPy(this), true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <[email protected]> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef ASSEMBLY_ViewGroup_H
|
||||
#define ASSEMBLY_ViewGroup_H
|
||||
|
||||
#include <Mod/Assembly/AssemblyGlobal.h>
|
||||
|
||||
#include <App/DocumentObjectGroup.h>
|
||||
#include <App/PropertyLinks.h>
|
||||
|
||||
|
||||
namespace Assembly
|
||||
{
|
||||
|
||||
class AssemblyExport ViewGroup: public App::DocumentObjectGroup
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Assembly::ViewGroup);
|
||||
|
||||
public:
|
||||
ViewGroup();
|
||||
~ViewGroup() override;
|
||||
|
||||
PyObject* getPyObject() override;
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "AssemblyGui::ViewProviderViewGroup";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace Assembly
|
||||
|
||||
|
||||
#endif // ASSEMBLY_ViewGroup_H
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
|
||||
<PythonExport
|
||||
Father="DocumentObjectGroupPy"
|
||||
Name="ViewGroupPy"
|
||||
Twin="ViewGroup"
|
||||
TwinPointer="ViewGroup"
|
||||
Include="Mod/Assembly/App/ViewGroup.h"
|
||||
Namespace="Assembly"
|
||||
FatherInclude="App/DocumentObjectGroupPy.h"
|
||||
FatherNamespace="App">
|
||||
<Documentation>
|
||||
<Author Licence="LGPL" Name="Ondsel" EMail="[email protected]" />
|
||||
<UserDocu>This class is a group subclass for joints.</UserDocu>
|
||||
</Documentation>
|
||||
|
||||
<CustomAttributes />
|
||||
</PythonExport>
|
||||
</GenerateModel>
|
||||
@@ -0,0 +1,46 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2014 Jürgen Riegel <[email protected]> *
|
||||
* *
|
||||
* 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"
|
||||
|
||||
// inclusion of the generated files (generated out of ViewGroup.xml)
|
||||
#include "ViewGroupPy.h"
|
||||
#include "ViewGroupPy.cpp"
|
||||
|
||||
using namespace Assembly;
|
||||
|
||||
// returns a string which represents the object e.g. when printed in python
|
||||
std::string ViewGroupPy::representation() const
|
||||
{
|
||||
return {"<Exploded View Group>"};
|
||||
}
|
||||
|
||||
PyObject* ViewGroupPy::getCustomAttributes(const char* /*attr*/) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int ViewGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -10,6 +10,7 @@ set(Assembly_Scripts
|
||||
CommandInsertLink.py
|
||||
CommandSolveAssembly.py
|
||||
CommandCreateJoint.py
|
||||
CommandCreateView.py
|
||||
CommandExportASMT.py
|
||||
TestAssemblyWorkbench.py
|
||||
JointObject.py
|
||||
|
||||
@@ -0,0 +1,866 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
# /**************************************************************************
|
||||
# *
|
||||
# Copyright (c) 2023 Ondsel <[email protected]> *
|
||||
# *
|
||||
# This file is part of FreeCAD. *
|
||||
# *
|
||||
# FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# under the terms of the GNU Lesser General Public License as *
|
||||
# published by the Free Software Foundation, either version 2.1 of the *
|
||||
# License, or (at your option) any later version. *
|
||||
# *
|
||||
# FreeCAD 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 *
|
||||
# Lesser General Public License for more details. *
|
||||
# *
|
||||
# You should have received a copy of the GNU Lesser General Public *
|
||||
# License along with FreeCAD. If not, see *
|
||||
# <https://www.gnu.org/licenses/>. *
|
||||
# *
|
||||
# **************************************************************************/
|
||||
|
||||
import re
|
||||
import os
|
||||
import FreeCAD as App
|
||||
|
||||
from pivy import coin
|
||||
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
|
||||
if App.GuiUp:
|
||||
import FreeCADGui as Gui
|
||||
from PySide import QtCore, QtGui, QtWidgets
|
||||
from PySide.QtWidgets import QPushButton, QMenu
|
||||
|
||||
import UtilsAssembly
|
||||
import Preferences
|
||||
|
||||
# translate = App.Qt.translate
|
||||
|
||||
__title__ = "Assembly Command Create Exploded View"
|
||||
__author__ = "Ondsel"
|
||||
__url__ = "https://www.freecad.org"
|
||||
|
||||
|
||||
class CommandCreateView:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def GetResources(self):
|
||||
return {
|
||||
"Pixmap": "Assembly_ExplodedView",
|
||||
"MenuText": QT_TRANSLATE_NOOP("Assembly_CreateView", "Create Exploded View"),
|
||||
"Accel": "V",
|
||||
"ToolTip": "<p>"
|
||||
+ QT_TRANSLATE_NOOP(
|
||||
"Assembly_CreateView",
|
||||
"Create an exploded view of the current assembly.",
|
||||
)
|
||||
+ "</p>",
|
||||
"CmdType": "ForEdit",
|
||||
}
|
||||
|
||||
def IsActive(self):
|
||||
return UtilsAssembly.isAssemblyCommandActive()
|
||||
|
||||
def Activated(self):
|
||||
assembly = UtilsAssembly.activeAssembly()
|
||||
if not assembly:
|
||||
return
|
||||
|
||||
self.panel = TaskAssemblyCreateView()
|
||||
Gui.Control.showDialog(self.panel)
|
||||
|
||||
|
||||
######### Exploded View Object ###########
|
||||
class ExplodedView:
|
||||
def __init__(self, expView):
|
||||
expView.addProperty(
|
||||
"App::PropertyLinkList", "Steps", "Exploded View", "Step objects of the exploded view."
|
||||
)
|
||||
expView.Proxy = self
|
||||
|
||||
self.stepsChangedCallback = None
|
||||
|
||||
def dumps(self):
|
||||
return None
|
||||
|
||||
def loads(self, state):
|
||||
return None
|
||||
|
||||
def getAssembly(self, viewObj):
|
||||
return viewObj.InList[0]
|
||||
|
||||
def onChanged(self, viewObj, prop):
|
||||
if prop == "Steps" and self.stepsChangedCallback is not None:
|
||||
self.stepsChangedCallback()
|
||||
|
||||
def setStepsChangedCallback(self, callback):
|
||||
self.stepsChangedCallback = callback
|
||||
|
||||
def execute(self, fp):
|
||||
"""Do something when doing a recomputation, this method is mandatory"""
|
||||
# App.Console.PrintMessage("Recompute Python Box feature\n")
|
||||
pass
|
||||
|
||||
|
||||
class ViewProviderExplodedView:
|
||||
def __init__(self, vobj):
|
||||
"""Set this object to the proxy object of the actual view provider"""
|
||||
vobj.Proxy = self
|
||||
|
||||
def attach(self, vobj):
|
||||
"""Setup the scene sub-graph of the view provider, this method is mandatory"""
|
||||
self.app_obj = vobj.Object
|
||||
|
||||
self.display_mode = coin.SoType.fromName("SoFCSelection").createInstance()
|
||||
|
||||
vobj.addDisplayMode(self.display_mode, "Wireframe")
|
||||
|
||||
def updateData(self, joint, prop):
|
||||
"""If a property of the handled feature has changed we have the chance to handle this here"""
|
||||
# joint is the handled feature, prop is the name of the property that has changed
|
||||
pass
|
||||
|
||||
def getDisplayModes(self, obj):
|
||||
"""Return a list of display modes."""
|
||||
return ["Wireframe"]
|
||||
|
||||
def getDefaultDisplayMode(self):
|
||||
"""Return the name of the default display mode. It must be defined in getDisplayModes."""
|
||||
return "Wireframe"
|
||||
|
||||
def onChanged(self, vp, prop):
|
||||
"""Here we can do something when a single property got changed"""
|
||||
# App.Console.PrintMessage("Change property: " + str(prop) + "\n")
|
||||
pass
|
||||
|
||||
def getIcon(self):
|
||||
return ":/icons/Assembly_ExplodedView.svg"
|
||||
|
||||
def dumps(self):
|
||||
"""When saving the document this object gets stored using Python's json module.\
|
||||
Since we have some un-serializable parts here -- the Coin stuff -- we must define this method\
|
||||
to return a tuple of all serializable objects or None."""
|
||||
return None
|
||||
|
||||
def loads(self, state):
|
||||
"""When restoring the serialized object from document we have the chance to set some internals here.\
|
||||
Since no data were serialized nothing needs to be done here."""
|
||||
return None
|
||||
|
||||
def claimChildren(self):
|
||||
return self.app_obj.Steps
|
||||
|
||||
def doubleClicked(self, vobj):
|
||||
task = Gui.Control.activeTaskDialog()
|
||||
if task:
|
||||
task.reject()
|
||||
|
||||
assembly = vobj.Object.InList[0]
|
||||
if UtilsAssembly.activeAssembly() != assembly:
|
||||
Gui.ActiveDocument.setEdit(assembly)
|
||||
|
||||
panel = TaskAssemblyCreateView(vobj.Object)
|
||||
Gui.Control.showDialog(panel)
|
||||
|
||||
|
||||
######### Exploded View Step #########
|
||||
ExplodedViewStepTypes = [
|
||||
"Normal",
|
||||
"Radial",
|
||||
]
|
||||
|
||||
|
||||
class ExplodedViewStep:
|
||||
def __init__(self, evStep, type_index=0):
|
||||
evStep.Proxy = self
|
||||
|
||||
# we cannot use "App::PropertyLinkList" for objs because they can be external
|
||||
evStep.addProperty(
|
||||
"App::PropertyStringList",
|
||||
"ObjNames",
|
||||
"Exploded Step",
|
||||
QT_TRANSLATE_NOOP("App::Property", "The object moved by the move"),
|
||||
)
|
||||
|
||||
evStep.addProperty(
|
||||
"App::PropertyLinkList",
|
||||
"Parts",
|
||||
"Exploded Step",
|
||||
QT_TRANSLATE_NOOP("App::Property", "The containing parts of objects moved by the move"),
|
||||
)
|
||||
|
||||
evStep.addProperty(
|
||||
"App::PropertyPlacement",
|
||||
"Placement",
|
||||
"Exploded Step",
|
||||
QT_TRANSLATE_NOOP(
|
||||
"App::Property",
|
||||
"This is the movement of the step. The end placement is the result of the start placement * this placement.",
|
||||
),
|
||||
)
|
||||
|
||||
evStep.addProperty(
|
||||
"App::PropertyEnumeration",
|
||||
"MoveType",
|
||||
"Exploded Step",
|
||||
QT_TRANSLATE_NOOP("App::Property", "The type of the move"),
|
||||
)
|
||||
evStep.MoveType = ExplodedViewStepTypes # sets the list
|
||||
evStep.MoveType = ExplodedViewStepTypes[type_index] # set the initial value
|
||||
|
||||
def dumps(self):
|
||||
return None
|
||||
|
||||
def loads(self, state):
|
||||
return None
|
||||
|
||||
def onChanged(self, joint, prop):
|
||||
"""Do something when a property has changed"""
|
||||
pass
|
||||
|
||||
def execute(self, fp):
|
||||
"""Do something when doing a recomputation, this method is mandatory"""
|
||||
# App.Console.PrintMessage("Recompute Python Box feature\n")
|
||||
pass
|
||||
|
||||
|
||||
class ViewProviderExplodedViewStep:
|
||||
def __init__(self, vobj):
|
||||
"""Set this object to the proxy object of the actual view provider"""
|
||||
vobj.Proxy = self
|
||||
|
||||
def attach(self, vobj):
|
||||
"""Setup the scene sub-graph of the view provider, this method is mandatory"""
|
||||
self.app_obj = vobj.Object
|
||||
|
||||
pref = Preferences.preferences()
|
||||
|
||||
self.line_thickness = pref.GetInt("StepLineThickness", 3)
|
||||
|
||||
param_step_line_color = pref.GetUnsigned("StepLineColor", 0xCC333300)
|
||||
self.so_color = coin.SoBaseColor()
|
||||
self.so_color.rgb.setValue(UtilsAssembly.color_from_unsigned(param_step_line_color))
|
||||
|
||||
self.draw_style = coin.SoDrawStyle()
|
||||
self.draw_style.style = coin.SoDrawStyle.LINES
|
||||
self.draw_style.lineWidth = self.line_thickness
|
||||
self.draw_style.linePattern = 0xF0F0 # Dashed line pattern
|
||||
|
||||
# Create a separator to hold all dashed lines
|
||||
self.lineSetGroup = coin.SoSeparator()
|
||||
|
||||
self.display_mode = coin.SoType.fromName("SoFCSelection").createInstance()
|
||||
self.display_mode.addChild(self.lineSetGroup) # Add the group to the display mode
|
||||
vobj.addDisplayMode(self.display_mode, "Wireframe")
|
||||
|
||||
if self.app_obj.MoveType == "Radial":
|
||||
assembly = UtilsAssembly.activeAssembly()
|
||||
self.assemblyCOM = UtilsAssembly.getCenterOfBoundingBox([assembly], [None])
|
||||
self.assemblyCOMSize = assembly.ViewObject.getBoundingBox().DiagonalLength
|
||||
|
||||
def updateData(self, stepObj, prop):
|
||||
"""If a property of the handled feature has changed we have the chance to handle this here"""
|
||||
# stepObj is the handled feature, prop is the name of the property that has changed
|
||||
if prop in ["Parts", "Placement"]:
|
||||
self.redrawLines(stepObj)
|
||||
|
||||
def redrawLines(self, stepObj):
|
||||
# Clear existing lines
|
||||
self.lineSetGroup.removeAllChildren()
|
||||
|
||||
if hasattr(stepObj, "Parts") and stepObj.Parts:
|
||||
if stepObj.MoveType == "Radial":
|
||||
distance = stepObj.Placement.Base.Length
|
||||
factor = 1 + 4 * distance / self.assemblyCOMSize
|
||||
|
||||
for objName, part in zip(stepObj.ObjNames, stepObj.Parts):
|
||||
if not objName:
|
||||
return
|
||||
|
||||
obj = UtilsAssembly.getObjectInPart(objName, part)
|
||||
|
||||
if not obj:
|
||||
return
|
||||
|
||||
plc2 = UtilsAssembly.getGlobalPlacement(obj, part)
|
||||
plc2.Base = UtilsAssembly.getCenterOfBoundingBox([obj], [part])
|
||||
endPoint = plc2.Base
|
||||
|
||||
if stepObj.MoveType == "Radial":
|
||||
startPoint = (endPoint - self.assemblyCOM) / factor + self.assemblyCOM
|
||||
|
||||
else:
|
||||
plc1 = stepObj.Placement.inverse() * plc2
|
||||
startPoint = plc1.Base
|
||||
|
||||
# Create the line
|
||||
line = coin.SoLineSet()
|
||||
line.numVertices.setValue(2)
|
||||
coords = coin.SoCoordinate3()
|
||||
coords.point.setValues(0, [startPoint, endPoint])
|
||||
|
||||
# Create separator for this line to apply the style
|
||||
line_sep = coin.SoSeparator()
|
||||
line_sep.addChild(self.draw_style)
|
||||
line_sep.addChild(self.so_color)
|
||||
line_sep.addChild(coords)
|
||||
line_sep.addChild(line)
|
||||
|
||||
# Add to the group
|
||||
self.lineSetGroup.addChild(line_sep)
|
||||
|
||||
def getDisplayModes(self, obj):
|
||||
"""Return a list of display modes."""
|
||||
modes = []
|
||||
modes.append("Wireframe")
|
||||
return modes
|
||||
|
||||
def getDefaultDisplayMode(self):
|
||||
"""Return the name of the default display mode. It must be defined in getDisplayModes."""
|
||||
return "Wireframe"
|
||||
|
||||
def onChanged(self, vp, prop):
|
||||
"""Here we can do something when a single property got changed"""
|
||||
# App.Console.PrintMessage("Change property: " + str(prop) + "\n")
|
||||
pass
|
||||
|
||||
def getIcon(self):
|
||||
return ":/icons/Assembly_ExplodedViewStep.svg"
|
||||
|
||||
def dumps(self):
|
||||
"""When saving the document this object gets stored using Python's json module.\
|
||||
Since we have some un-serializable parts here -- the Coin stuff -- we must define this method\
|
||||
to return a tuple of all serializable objects or None."""
|
||||
return None
|
||||
|
||||
def loads(self, state):
|
||||
"""When restoring the serialized object from document we have the chance to set some internals here.\
|
||||
Since no data were serialized nothing needs to be done here."""
|
||||
return None
|
||||
|
||||
|
||||
class ExplodedViewSelGate:
|
||||
def __init__(self, assembly, viewObj):
|
||||
self.assembly = assembly
|
||||
self.viewObj = viewObj
|
||||
|
||||
def allow(self, doc, obj, sub):
|
||||
if (obj.Name == self.assembly.Name and sub) or self.assembly.hasObject(obj, True):
|
||||
# Objects within the assembly.
|
||||
return True
|
||||
|
||||
if obj in self.viewObj.Steps:
|
||||
# Enable selection of steps object
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
######### Create Exploded View Task ###########
|
||||
class TaskAssemblyCreateView(QtCore.QObject):
|
||||
def __init__(self, viewObj=None):
|
||||
super().__init__()
|
||||
|
||||
view = Gui.activeDocument().activeView()
|
||||
|
||||
self.assembly = UtilsAssembly.activeAssembly()
|
||||
self.assembly.ViewObject.EnableMovement = False
|
||||
self.asmDragger = self.assembly.ViewObject.getDragger()
|
||||
self.cbFin = view.addDraggerCallback(
|
||||
self.asmDragger, "addFinishCallback", self.draggerFinished
|
||||
)
|
||||
self.cbMov = view.addDraggerCallback(
|
||||
self.asmDragger, "addMotionCallback", self.draggerMoved
|
||||
)
|
||||
|
||||
self.assemblyCOM = UtilsAssembly.getCenterOfBoundingBox([self.assembly], [None])
|
||||
self.assemblyCOMSize = self.assembly.ViewObject.getBoundingBox().DiagonalLength
|
||||
|
||||
# self.doc = App.ActiveDocument
|
||||
|
||||
Gui.Selection.clearSelection()
|
||||
|
||||
self.form = Gui.PySideUic.loadUi(":/panels/TaskAssemblyCreateView.ui")
|
||||
self.form.stepList.installEventFilter(self)
|
||||
self.form.stepList.itemClicked.connect(self.onItemClicked)
|
||||
|
||||
self.form.btnAlignDragger.setMenu(QMenu(self.form.btnAlignDragger))
|
||||
actionAlignTo = self.form.btnAlignDragger.menu().addAction("Align to...")
|
||||
actionAlignToCenter = self.form.btnAlignDragger.menu().addAction("Align to part center")
|
||||
actionAlignToOrigin = self.form.btnAlignDragger.menu().addAction("Align to part origin")
|
||||
|
||||
# Connect actions to the respective functions
|
||||
actionAlignTo.triggered.connect(self.onAlignTo)
|
||||
actionAlignToCenter.triggered.connect(self.onAlignToCenter)
|
||||
actionAlignToOrigin.triggered.connect(self.onAlignToPartOrigin)
|
||||
|
||||
self.form.btnAlignDragger.setVisible(False)
|
||||
self.form.btnRadialExplosion.clicked.connect(self.onRadialClicked)
|
||||
|
||||
pref = Preferences.preferences()
|
||||
self.form.CheckBox_PartsAsSingleSolid.setChecked(pref.GetBool("PartsAsSingleSolid", True))
|
||||
|
||||
self.saveAssemblyPartsPlacements(self.assembly)
|
||||
|
||||
if viewObj:
|
||||
App.setActiveTransaction("Edit Exploded View")
|
||||
self.viewObj = viewObj
|
||||
for step in self.viewObj.Steps:
|
||||
step.Visibility = True
|
||||
self.onStepsChanged()
|
||||
|
||||
else:
|
||||
App.setActiveTransaction("Create Exploded View")
|
||||
self.createExplodedViewObject()
|
||||
|
||||
Gui.Selection.addSelectionGate(
|
||||
ExplodedViewSelGate(self.assembly, self.viewObj), Gui.Selection.ResolveMode.NoResolve
|
||||
)
|
||||
Gui.Selection.addObserver(self, Gui.Selection.ResolveMode.NoResolve)
|
||||
|
||||
self.viewObj.Proxy.setStepsChangedCallback(self.onStepsChanged)
|
||||
self.callbackMove = view.addEventCallback("SoLocation2Event", self.moveMouse)
|
||||
self.callbackClick = view.addEventCallback("SoMouseButtonEvent", self.clickMouse)
|
||||
self.callbackKey = view.addEventCallback("SoKeyboardEvent", self.KeyboardEvent)
|
||||
|
||||
self.selectingFeature = False
|
||||
self.form.LabelAlignDragger.setVisible(False)
|
||||
self.preselection_dict = None
|
||||
|
||||
self.blockSetDragger = False
|
||||
self.blockDraggerMove = True
|
||||
self.currentStep = None
|
||||
|
||||
def accept(self):
|
||||
self.deactivate()
|
||||
self.restoreAssemblyPartsPlacements(self.assembly)
|
||||
for step in self.viewObj.Steps:
|
||||
step.Visibility = False
|
||||
App.closeActiveTransaction()
|
||||
return True
|
||||
|
||||
def reject(self):
|
||||
self.deactivate()
|
||||
App.closeActiveTransaction(True)
|
||||
return True
|
||||
|
||||
def deactivate(self):
|
||||
pref = Preferences.preferences()
|
||||
pref.SetBool("PartsAsSingleSolid", self.form.CheckBox_PartsAsSingleSolid.isChecked())
|
||||
|
||||
view = Gui.activeDocument().activeView()
|
||||
view.removeDraggerCallback(self.asmDragger, "addFinishCallback", self.cbFin)
|
||||
view.removeDraggerCallback(self.asmDragger, "addMotionCallback", self.cbMov)
|
||||
|
||||
self.assembly.ViewObject.DraggerVisibility = False
|
||||
self.assembly.ViewObject.EnableMovement = True
|
||||
|
||||
Gui.Selection.removeSelectionGate()
|
||||
Gui.Selection.removeObserver(self)
|
||||
Gui.Selection.clearSelection()
|
||||
|
||||
self.viewObj.Proxy.setStepsChangedCallback(None)
|
||||
view.removeEventCallback("SoLocation2Event", self.callbackMove)
|
||||
view.removeEventCallback("SoMouseButtonEvent", self.callbackClick)
|
||||
view.removeEventCallback("SoKeyboardEvent", self.callbackKey)
|
||||
|
||||
if Gui.Control.activeDialog():
|
||||
Gui.Control.closeDialog()
|
||||
|
||||
def saveAssemblyPartsPlacements(self, assembly):
|
||||
self.initialPlcDict = {}
|
||||
assemblyParts = UtilsAssembly.getMovablePartsWithin(assembly)
|
||||
for part in assemblyParts:
|
||||
self.initialPlcDict[part.Name] = part.Placement
|
||||
|
||||
def restoreAssemblyPartsPlacements(self, assembly):
|
||||
assemblyParts = UtilsAssembly.getMovablePartsWithin(assembly)
|
||||
for part in assemblyParts:
|
||||
if part.Name in self.initialPlcDict:
|
||||
part.Placement = self.initialPlcDict[part.Name]
|
||||
|
||||
def setDragger(self):
|
||||
if self.blockSetDragger:
|
||||
return
|
||||
|
||||
self.dismissCurrentStep()
|
||||
self.selectedObjs = []
|
||||
self.selectedParts = [] # containing parts
|
||||
self.selectedObjsInitPlc = []
|
||||
selection = Gui.Selection.getSelectionEx("*", 0)
|
||||
if not selection:
|
||||
self.enableDragger(False)
|
||||
return
|
||||
for sel in selection:
|
||||
# If you select 2 solids (bodies for example) within an assembly.
|
||||
# There'll be a single sel but 2 SubElementNames.
|
||||
|
||||
if not sel.SubElementNames:
|
||||
# no subnames, so its a root assembly itself that is selected.
|
||||
Gui.Selection.removeSelection(sel.Object)
|
||||
continue
|
||||
|
||||
for sub_name in sel.SubElementNames:
|
||||
# Only objects within the assembly.
|
||||
objs_names, element_name = UtilsAssembly.getObjsNamesAndElement(
|
||||
sel.ObjectName, sub_name
|
||||
)
|
||||
if self.assembly.Name not in objs_names:
|
||||
Gui.Selection.removeSelection(sel.Object, sub_name)
|
||||
continue
|
||||
|
||||
obj_name = sel.ObjectName
|
||||
full_obj_name = UtilsAssembly.getFullObjName(obj_name, sub_name)
|
||||
full_element_name = UtilsAssembly.getFullElementName(obj_name, sub_name)
|
||||
selected_object = UtilsAssembly.getObject(full_element_name)
|
||||
if selected_object is None:
|
||||
continue
|
||||
element_name = UtilsAssembly.getElementName(full_element_name)
|
||||
part = UtilsAssembly.getContainingPart(
|
||||
full_element_name, selected_object, self.assembly
|
||||
)
|
||||
|
||||
if selected_object == self.assembly or element_name != "":
|
||||
# do not accept selection of assembly itself or elements
|
||||
Gui.Selection.removeSelection(sel.Object, sub_name)
|
||||
continue
|
||||
|
||||
if self.form.CheckBox_PartsAsSingleSolid.isChecked():
|
||||
selected_object = part
|
||||
|
||||
if not selected_object in self.selectedObjs and hasattr(
|
||||
selected_object, "Placement"
|
||||
):
|
||||
self.selectedObjs.append(selected_object)
|
||||
self.selectedParts.append(part)
|
||||
self.selectedObjsInitPlc.append(App.Placement(selected_object.Placement))
|
||||
|
||||
if len(self.selectedObjs) != 0:
|
||||
self.enableDragger(True)
|
||||
self.onAlignToCenter()
|
||||
|
||||
else:
|
||||
self.enableDragger(False)
|
||||
|
||||
def enableDragger(self, val):
|
||||
self.assembly.ViewObject.DraggerVisibility = val
|
||||
self.form.btnAlignDragger.setVisible(val)
|
||||
|
||||
def onStepsChanged(self):
|
||||
# First reset positions
|
||||
self.restoreAssemblyPartsPlacements(self.assembly)
|
||||
|
||||
self.form.stepList.clear()
|
||||
|
||||
for step in self.viewObj.Steps:
|
||||
|
||||
if step.MoveType == "Radial":
|
||||
distance = step.Placement.Base.Length
|
||||
factor = 1 + 4 * distance / self.assemblyCOMSize
|
||||
|
||||
for objName, part in zip(step.ObjNames, step.Parts):
|
||||
obj = UtilsAssembly.getObjectInPart(objName, part)
|
||||
if not obj:
|
||||
continue
|
||||
|
||||
if step.MoveType == "Radial":
|
||||
init_vec = obj.Placement.Base - self.assemblyCOM
|
||||
obj.Placement.Base = self.assemblyCOM + init_vec * factor
|
||||
else:
|
||||
obj.Placement = step.Placement * obj.Placement
|
||||
|
||||
self.form.stepList.addItem(step.Name)
|
||||
step.ViewObject.Proxy.redrawLines(step)
|
||||
|
||||
def onItemClicked(self, item):
|
||||
Gui.Selection.clearSelection()
|
||||
Gui.Selection.addSelection(self.viewObj.Document.Name, item.text(), "")
|
||||
# we give back the focus to the item as addSelection gave the focus to the 3dview
|
||||
self.form.stepList.setCurrentItem(item)
|
||||
|
||||
def onRadialClicked(self):
|
||||
self.dismissCurrentStep()
|
||||
|
||||
# Add to selection all the movable parts
|
||||
partsAsSolid = self.form.CheckBox_PartsAsSingleSolid.isChecked()
|
||||
assemblyParts = UtilsAssembly.getMovablePartsWithin(self.assembly, partsAsSolid)
|
||||
self.blockSetDragger = True
|
||||
for part in assemblyParts:
|
||||
Gui.Selection.addSelection(part, "")
|
||||
self.blockSetDragger = False
|
||||
self.setDragger()
|
||||
|
||||
self.createExplodedStepObject(1) # 1 = type_index of "Radial"
|
||||
|
||||
def onAlignTo(self):
|
||||
self.alignMode = "Custom"
|
||||
self.selectingFeature = True
|
||||
# We use greedy selection to prevent that clicking again on the solid
|
||||
# clears selection before trying to select the whole assemly
|
||||
Gui.Selection.setSelectionStyle(Gui.Selection.SelectionStyle.GreedySelection)
|
||||
self.enableDragger(False)
|
||||
self.form.LabelAlignDragger.setVisible(True)
|
||||
|
||||
def endSelectionMode(self):
|
||||
self.selectingFeature = False
|
||||
self.enableDragger(True)
|
||||
Gui.Selection.setSelectionStyle(Gui.Selection.SelectionStyle.NormalSelection)
|
||||
self.form.LabelAlignDragger.setVisible(False)
|
||||
|
||||
def onAlignToCenter(self):
|
||||
self.alignMode = "Center"
|
||||
self.setDraggerObjectPlc()
|
||||
|
||||
def onAlignToPartOrigin(self):
|
||||
self.alignMode = "PartOrigin"
|
||||
self.setDraggerObjectPlc()
|
||||
|
||||
def findDraggerInitialPlc(self):
|
||||
if len(self.selectedObjs) == 0:
|
||||
return
|
||||
|
||||
if self.alignMode == "Custom":
|
||||
self.initialDraggerPlc = App.Placement(self.assembly.ViewObject.DraggerPlacement)
|
||||
else:
|
||||
plc = UtilsAssembly.getGlobalPlacement(self.selectedObjs[0], self.selectedParts[0])
|
||||
self.initialDraggerPlc = App.Placement(plc)
|
||||
if self.alignMode == "Center":
|
||||
self.initialDraggerPlc.Base = UtilsAssembly.getCenterOfBoundingBox(
|
||||
self.selectedObjs, self.selectedParts
|
||||
)
|
||||
|
||||
def setDraggerObjectPlc(self):
|
||||
self.findDraggerInitialPlc()
|
||||
|
||||
self.blockDraggerMove = True
|
||||
self.assembly.ViewObject.DraggerPlacement = self.initialDraggerPlc
|
||||
self.blockDraggerMove = False
|
||||
|
||||
def createExplodedViewObject(self):
|
||||
view_group = UtilsAssembly.getViewGroup(self.assembly)
|
||||
self.viewObj = view_group.newObject("App::FeaturePython", "Exploded View")
|
||||
|
||||
ExplodedView(self.viewObj)
|
||||
ViewProviderExplodedView(self.viewObj.ViewObject)
|
||||
|
||||
def createExplodedStepObject(self, moveType_index=0):
|
||||
self.currentStep = App.ActiveDocument.addObject("App::FeaturePython", "Move")
|
||||
ExplodedViewStep(self.currentStep, moveType_index)
|
||||
ViewProviderExplodedViewStep(self.currentStep.ViewObject)
|
||||
|
||||
# Note: self.viewObj.Steps.append(self.currentStep) does not work
|
||||
listOfSteps = self.viewObj.Steps
|
||||
listOfSteps.append(self.currentStep)
|
||||
self.viewObj.Steps = listOfSteps
|
||||
|
||||
objNames = []
|
||||
for obj in self.selectedObjs:
|
||||
objNames.append(obj.Name)
|
||||
|
||||
self.currentStep.Placement = App.Placement()
|
||||
self.currentStep.ObjNames = objNames
|
||||
self.currentStep.Parts = self.selectedParts
|
||||
|
||||
def dismissCurrentStep(self):
|
||||
if self.currentStep is None:
|
||||
return
|
||||
|
||||
for obj, init_plc in zip(self.selectedObjs, self.selectedObjsInitPlc):
|
||||
obj.Placement = init_plc
|
||||
|
||||
self.currentStep.Document.removeObject(self.currentStep.Name)
|
||||
self.currentStep = None
|
||||
|
||||
Gui.Selection.clearSelection()
|
||||
|
||||
def draggerMoved(self, event):
|
||||
if self.blockDraggerMove:
|
||||
return
|
||||
|
||||
if self.currentStep is None:
|
||||
self.createExplodedStepObject()
|
||||
|
||||
draggerPlc = self.assembly.ViewObject.DraggerPlacement
|
||||
movePlc = draggerPlc * self.initialDraggerPlc.inverse()
|
||||
|
||||
if self.currentStep.MoveType == "Radial":
|
||||
distance = movePlc.Base.Length
|
||||
factor = 1 + 4 * distance / self.assemblyCOMSize
|
||||
for obj, init_plc in zip(self.selectedObjs, self.selectedObjsInitPlc):
|
||||
init_vec = init_plc.Base - self.assemblyCOM
|
||||
obj.Placement.Base = self.assemblyCOM + init_vec * factor
|
||||
|
||||
else:
|
||||
for obj, init_plc in zip(self.selectedObjs, self.selectedObjsInitPlc):
|
||||
obj.Placement = movePlc * init_plc
|
||||
|
||||
# we update the step Placement after parts placement has updated.
|
||||
self.currentStep.Placement = movePlc
|
||||
|
||||
def draggerFinished(self, event):
|
||||
if self.currentStep.MoveType == "Radial":
|
||||
self.currentStep = None
|
||||
Gui.Selection.clearSelection()
|
||||
return
|
||||
|
||||
self.currentStep = None
|
||||
|
||||
# Reset the initial placements
|
||||
self.findDraggerInitialPlc()
|
||||
|
||||
for i, obj in enumerate(self.selectedObjs):
|
||||
self.selectedObjsInitPlc[i] = App.Placement(obj.Placement)
|
||||
|
||||
def moveMouse(self, info):
|
||||
if not self.selectingFeature:
|
||||
return
|
||||
|
||||
view = Gui.activeDocument().activeView()
|
||||
cursor_info = view.getObjectInfo(view.getCursorPos())
|
||||
|
||||
if not cursor_info or not self.preselection_dict:
|
||||
self.assembly.ViewObject.DraggerVisibility = False
|
||||
return
|
||||
|
||||
newPos = App.Vector(cursor_info["x"], cursor_info["y"], cursor_info["z"])
|
||||
self.preselection_dict["mouse_pos"] = newPos
|
||||
|
||||
if self.preselection_dict["element_name"] == "":
|
||||
self.preselection_dict["vertex_name"] = ""
|
||||
else:
|
||||
self.preselection_dict["vertex_name"] = UtilsAssembly.findElementClosestVertex(
|
||||
self.preselection_dict
|
||||
)
|
||||
|
||||
obj = self.preselection_dict["object"]
|
||||
part = self.preselection_dict["part"]
|
||||
plc = UtilsAssembly.findPlacement(
|
||||
obj,
|
||||
part,
|
||||
self.preselection_dict["element_name"],
|
||||
self.preselection_dict["vertex_name"],
|
||||
)
|
||||
global_plc = UtilsAssembly.getGlobalPlacement(obj, part)
|
||||
plc = global_plc * plc
|
||||
|
||||
self.blockDraggerMove = True
|
||||
self.assembly.ViewObject.DraggerPlacement = plc
|
||||
self.blockDraggerMove = False
|
||||
self.assembly.ViewObject.DraggerVisibility = True
|
||||
|
||||
def clickMouse(self, info):
|
||||
if info["Button"] == "BUTTON2" and info["State"] == "DOWN":
|
||||
if self.selectingFeature:
|
||||
self.endSelectionMode()
|
||||
|
||||
# 3D view keyboard handler
|
||||
def KeyboardEvent(self, info):
|
||||
if info["State"] == "UP" and info["Key"] == "ESCAPE":
|
||||
if self.currentStep is None:
|
||||
self.reject()
|
||||
else:
|
||||
if self.selectingFeature:
|
||||
self.endSelectionMode()
|
||||
else:
|
||||
self.dismissCurrentStep()
|
||||
|
||||
# Taskbox keyboard event handler
|
||||
def eventFilter(self, watched, event):
|
||||
if self.form is not None and watched == self.form.stepList:
|
||||
if event.type() == QtCore.QEvent.ShortcutOverride:
|
||||
if event.key() == QtCore.Qt.Key_Delete:
|
||||
event.accept()
|
||||
return True # Indicate that the event has been handled
|
||||
return False
|
||||
|
||||
elif event.type() == QtCore.QEvent.KeyPress:
|
||||
if event.key() == QtCore.Qt.Key_Delete:
|
||||
selected_indexes = self.form.stepList.selectedIndexes()
|
||||
sorted_indexes = sorted(selected_indexes, key=lambda x: x.row(), reverse=True)
|
||||
for index in sorted_indexes:
|
||||
row = index.row()
|
||||
if row < len(self.viewObj.Steps):
|
||||
step = self.viewObj.Steps[row]
|
||||
# First remove the link from the viewObj
|
||||
self.viewObj.Steps.remove(step)
|
||||
# Delete the object
|
||||
step.Document.removeObject(step.Name)
|
||||
|
||||
return True # Consume the event
|
||||
|
||||
return super().eventFilter(watched, event)
|
||||
|
||||
# selectionObserver stuff
|
||||
def addSelection(self, doc_name, obj_name, sub_name, mousePos):
|
||||
if self.selectingFeature:
|
||||
Gui.Selection.removeSelection(doc_name, obj_name, sub_name)
|
||||
return
|
||||
|
||||
else:
|
||||
full_element_name = UtilsAssembly.getFullElementName(obj_name, sub_name)
|
||||
selected_object = UtilsAssembly.getObject(full_element_name)
|
||||
if selected_object is None:
|
||||
return
|
||||
|
||||
element_name = UtilsAssembly.getElementName(full_element_name)
|
||||
part = UtilsAssembly.getContainingPart(
|
||||
full_element_name, selected_object, self.assembly
|
||||
)
|
||||
|
||||
if not self.form.CheckBox_PartsAsSingleSolid.isChecked():
|
||||
part = selected_object
|
||||
|
||||
if element_name != "":
|
||||
# When selecting, we do not want to select an element, but only the containing part.
|
||||
Gui.Selection.removeSelection(selected_object, element_name)
|
||||
if Gui.Selection.isSelected(part, ""):
|
||||
Gui.Selection.removeSelection(part, "")
|
||||
else:
|
||||
Gui.Selection.addSelection(part, "")
|
||||
else:
|
||||
self.setDragger()
|
||||
pass
|
||||
|
||||
def removeSelection(self, doc_name, obj_name, sub_name, mousePos=None):
|
||||
if self.selectingFeature:
|
||||
self.endSelectionMode()
|
||||
self.findDraggerInitialPlc()
|
||||
return
|
||||
|
||||
full_element_name = UtilsAssembly.getFullElementName(obj_name, sub_name)
|
||||
element_name = UtilsAssembly.getElementName(full_element_name)
|
||||
if element_name == "":
|
||||
self.setDragger()
|
||||
pass
|
||||
|
||||
def setPreselection(self, doc_name, obj_name, sub_name):
|
||||
if not self.selectingFeature or not sub_name:
|
||||
self.preselection_dict = None
|
||||
return
|
||||
|
||||
full_obj_name = UtilsAssembly.getFullObjName(obj_name, sub_name)
|
||||
full_element_name = UtilsAssembly.getFullElementName(obj_name, sub_name)
|
||||
selected_object = UtilsAssembly.getObject(full_element_name)
|
||||
element_name = UtilsAssembly.getElementName(full_element_name)
|
||||
part = UtilsAssembly.getContainingPart(full_element_name, selected_object, self.assembly)
|
||||
|
||||
self.preselection_dict = {
|
||||
"object": selected_object,
|
||||
"part": part,
|
||||
"sub_name": sub_name,
|
||||
"element_name": element_name,
|
||||
"full_element_name": full_element_name,
|
||||
"full_obj_name": full_obj_name,
|
||||
}
|
||||
|
||||
def clearSelection(self, doc_name):
|
||||
self.form.stepList.clearSelection()
|
||||
self.setDragger()
|
||||
|
||||
|
||||
if App.GuiUp:
|
||||
Gui.addCommand("Assembly_CreateView", CommandCreateView())
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "ViewProviderAssembly.h"
|
||||
#include "ViewProviderJointGroup.h"
|
||||
#include "ViewProviderViewGroup.h"
|
||||
|
||||
|
||||
namespace AssemblyGui
|
||||
@@ -48,6 +49,7 @@ PyMOD_INIT_FUNC(AssemblyGui)
|
||||
|
||||
AssemblyGui::ViewProviderAssembly ::init();
|
||||
AssemblyGui::ViewProviderJointGroup::init();
|
||||
AssemblyGui::ViewProviderViewGroup::init();
|
||||
|
||||
PyMOD_Return(mod);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,8 @@ SET(AssemblyGui_SRCS_Module
|
||||
ViewProviderAssembly.h
|
||||
ViewProviderJointGroup.cpp
|
||||
ViewProviderJointGroup.h
|
||||
ViewProviderViewGroup.cpp
|
||||
ViewProviderViewGroup.h
|
||||
${Assembly_QRC_SRCS}
|
||||
)
|
||||
|
||||
|
||||
@@ -13,8 +13,11 @@
|
||||
<file>icons/Assembly_ExportASMT.svg</file>
|
||||
<file>icons/Assembly_SolveAssembly.svg</file>
|
||||
<file>icons/Assembly_JointGroup.svg</file>
|
||||
<file>icons/Assembly_ExplodedView.svg</file>
|
||||
<file>icons/Assembly_ExplodedViewGroup.svg</file>
|
||||
<file>panels/TaskAssemblyCreateJoint.ui</file>
|
||||
<file>panels/TaskAssemblyInsertLink.ui</file>
|
||||
<file>panels/TaskAssemblyCreateView.ui</file>
|
||||
<file>preferences/Assembly.ui</file>
|
||||
<file>icons/Assembly_CreateJointDistance.svg</file>
|
||||
<file>icons/AssemblyWorkbench.svg</file>
|
||||
|
||||
@@ -0,0 +1,405 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="64"
|
||||
height="64"
|
||||
version="1.1"
|
||||
viewBox="0 0 64 64"
|
||||
id="svg96"
|
||||
sodipodi:docname="Assembly_ExplodedView4.svg"
|
||||
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="2560"
|
||||
inkscape:window-height="1356"
|
||||
id="namedview98"
|
||||
showgrid="false"
|
||||
inkscape:zoom="7.375"
|
||||
inkscape:cx="38.983051"
|
||||
inkscape:cy="31.728814"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg96"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<defs
|
||||
id="defs26">
|
||||
<linearGradient
|
||||
id="linearGradient1"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#efdc3d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop1" />
|
||||
<stop
|
||||
style="stop-color:#bba80d;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4383">
|
||||
<stop
|
||||
stop-color="#3465a4"
|
||||
offset="0"
|
||||
id="stop2" />
|
||||
<stop
|
||||
stop-color="#729fcf"
|
||||
offset="1"
|
||||
id="stop4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4389"
|
||||
x1="20.244"
|
||||
x2="17.244"
|
||||
y1="37.588"
|
||||
y2="27.588"
|
||||
gradientTransform="translate(-1.2435,-2.5881)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient3774" />
|
||||
<linearGradient
|
||||
id="linearGradient4399"
|
||||
x1="48.714"
|
||||
x2="44.714"
|
||||
y1="45.586"
|
||||
y2="34.586"
|
||||
gradientTransform="translate(1.2856,1.4142)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="#c4a000"
|
||||
offset="0"
|
||||
id="stop8" />
|
||||
<stop
|
||||
stop-color="#edd400"
|
||||
offset="1"
|
||||
id="stop10" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient69042"
|
||||
x1="48.714"
|
||||
x2="44.714"
|
||||
y1="45.586"
|
||||
y2="34.586"
|
||||
gradientTransform="translate(-12.714,-17.586)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient3774" />
|
||||
<linearGradient
|
||||
id="linearGradient69056"
|
||||
x1="27.244"
|
||||
x2="22.244"
|
||||
y1="54.588"
|
||||
y2="40.588"
|
||||
gradientTransform="translate(-1.2435,-2.5881)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="#c4a000"
|
||||
offset="0"
|
||||
id="stop14" />
|
||||
<stop
|
||||
stop-color="#fce94f"
|
||||
offset="1"
|
||||
id="stop16" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient69709"
|
||||
x1="20.244"
|
||||
x2="17.244"
|
||||
y1="37.588"
|
||||
y2="27.588"
|
||||
gradientTransform="matrix(1,-0.026667,0,1,81.696,-5.3735)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient4383" />
|
||||
<linearGradient
|
||||
id="linearGradient69717"
|
||||
x1="50.714"
|
||||
x2="48.714"
|
||||
y1="25.586"
|
||||
y2="20.586"
|
||||
gradientTransform="translate(61.2256,1.0356)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient4383" />
|
||||
<linearGradient
|
||||
id="linearGradient3774">
|
||||
<stop
|
||||
stop-color="#4e9a06"
|
||||
offset="0"
|
||||
id="stop21" />
|
||||
<stop
|
||||
stop-color="#8ae234"
|
||||
offset="1"
|
||||
id="stop23" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient69056"
|
||||
id="linearGradient920"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-41.2435,-2.5881)"
|
||||
x1="20.243999"
|
||||
y1="37.588001"
|
||||
x2="17.243999"
|
||||
y2="27.587999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4399"
|
||||
id="linearGradient922"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-52.714,-17.586)"
|
||||
x1="48.714001"
|
||||
y1="45.585999"
|
||||
x2="44.714001"
|
||||
y2="34.585999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient69056"
|
||||
id="linearGradient3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-1.2435,-2.5881)"
|
||||
x1="27.244"
|
||||
y1="54.588"
|
||||
x2="22.244"
|
||||
y2="40.588" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4399"
|
||||
id="linearGradient4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(1.2856,1.4142)"
|
||||
x1="48.714"
|
||||
y1="45.586"
|
||||
x2="44.714"
|
||||
y2="34.586" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1"
|
||||
id="linearGradient5"
|
||||
x1="8.000092"
|
||||
y1="31.5"
|
||||
x2="55.999914"
|
||||
y2="31.5"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata28">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
<dc:title>Path-Stock</dc:title>
|
||||
<dc:date>2015-07-04</dc:date>
|
||||
<dc:relation>https://www.freecad.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/Path/Gui/Resources/icons/Path-Stock.svg</dc:identifier>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>[agryson] Alexander Gryson</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="g40"
|
||||
style="stroke-width:2"
|
||||
transform="matrix(0.80408661,0,0,0.80408661,4.9132963,13.143908)">
|
||||
<path
|
||||
d="M 9,49 V 35 l 28,10 v 14 z"
|
||||
id="path30"
|
||||
style="fill:url(#linearGradient3);stroke:#302b00;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 37,59 V 45 L 55,28 v 13 z"
|
||||
id="path32"
|
||||
style="fill:url(#linearGradient4);stroke:#302b00;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 11.008,47.606 11,37.9997 l 24,8 0.0081,10.185 z"
|
||||
id="path34"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#fce94f" />
|
||||
<path
|
||||
d="M 39.005,54.168 39,45.9998 l 14,-13 0.0021,7.1768 z"
|
||||
id="path36"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#edd400" />
|
||||
<path
|
||||
d="M 9,35 28,18 55,28 37,45 Z"
|
||||
id="path38"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient5);stroke:#302b00;stroke-linejoin:round"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
d="M 12.804336,34.208711 28.573658,19.940661 51.218486,28.771569 36.523799,42.772294 Z"
|
||||
id="path34-3"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
<path
|
||||
style="color:#000000;fill:#ef2929;stroke:#650707;stroke-width:0.8;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
d="m 24.481959,19.639029 a 1,1 0 0 0 -1,1 l 0.002,1.716797 a 1,1 0 0 0 1.001953,1 1,1 0 0 0 0.998047,-1.001953 l -0.002,-1.716797 a 1,1 0 0 0 -1,-0.998047 z m 0.0039,4.716797 a 1,1 0 0 0 -1,1 l 0.002,2 a 1,1 0 0 0 1.001953,1 1,1 0 0 0 0.998047,-1.001953 l -0.002,-2 a 1,1 0 0 0 -1,-0.998047 z m 0.0039,5 a 1,1 0 0 0 -0.998047,1 v 2 a 1,1 0 0 0 1.001953,1 1,1 0 0 0 0.998047,-1.001953 v -2 a 1,1 0 0 0 -1.001941,-0.998047 z m 0.0039,5 a 1,1 0 0 0 -0.998047,1 l 0.002,2 a 1,1 0 0 0 1,1 1,1 0 0 0 1,-1.001953 l -0.002,-2 a 1,1 0 0 0 -1.001935,-0.998047 z"
|
||||
id="path6" />
|
||||
<g
|
||||
display="none"
|
||||
fill="#ef2929"
|
||||
fill-rule="evenodd"
|
||||
opacity="0.588"
|
||||
stroke="#ef2929"
|
||||
stroke-width="1px"
|
||||
id="g94">
|
||||
<path
|
||||
d="M 9,35 V 49"
|
||||
id="path66" />
|
||||
<path
|
||||
d="M 9,35 37,45"
|
||||
id="path68" />
|
||||
<path
|
||||
d="M 55,28 V 41"
|
||||
id="path70" />
|
||||
<path
|
||||
d="M 37,45 55,28"
|
||||
id="path72" />
|
||||
<path
|
||||
d="M 23,40 V 26"
|
||||
id="path74" />
|
||||
<path
|
||||
d="m 29,5 13,5"
|
||||
id="path76" />
|
||||
<path
|
||||
d="M 23,26 42,10"
|
||||
id="path78" />
|
||||
<path
|
||||
d="M 19,13 29,5"
|
||||
id="path80" />
|
||||
<path
|
||||
d="m 55,15 -9,8"
|
||||
id="path82" />
|
||||
<path
|
||||
d="M 42,23 V 10"
|
||||
id="path84" />
|
||||
<path
|
||||
d="m 42,23 14,5"
|
||||
id="path86" />
|
||||
<path
|
||||
d="M 23,40 42,23"
|
||||
id="path88" />
|
||||
<path
|
||||
d="M 23,10 H 42"
|
||||
id="path90" />
|
||||
<path
|
||||
d="M 34,17 V 30"
|
||||
id="path92" />
|
||||
</g>
|
||||
<g
|
||||
id="g963"
|
||||
transform="matrix(0.80408661,0,0,0.80408661,31.929379,-0.96751733)">
|
||||
<g
|
||||
style="stroke:#172a04;stroke-width:2;stroke-linejoin:round"
|
||||
transform="translate(-40)"
|
||||
id="g48">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4389)"
|
||||
id="path42"
|
||||
d="M 9,35 V 21 l 14,5 v 14 z" />
|
||||
<path
|
||||
style="fill:#8ae234"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path44"
|
||||
d="M 9,21 28.585,5.209 42,10.0001 l -19,16 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient69042)"
|
||||
id="path46"
|
||||
d="M 23,40 V 26 l 7.9726,-6.7138 0.02739,13.714 z" />
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient920);fill-opacity:1;stroke:#172a04;stroke-width:2;stroke-linejoin:round"
|
||||
id="path912"
|
||||
d="M -31,35 V 21 l 14,5 v 14 z" />
|
||||
<path
|
||||
style="fill:#fce94f;fill-opacity:1;stroke:#172a04;stroke-width:2;stroke-linejoin:round;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path914"
|
||||
d="M -31,21 -11.415,5.209 2,10.0001 l -19,16 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient922);fill-opacity:1;stroke:#172a04;stroke-width:2;stroke-linejoin:round"
|
||||
id="path916"
|
||||
d="M -17,40 V 26 L 2,10.0001 2.0000003,23 Z"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
d="m -15,35.578425 v -9 L 0.08743031,14.309658 0.2139029,22.129247 Z"
|
||||
id="path50"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
d="m -29.049,33.746 0.08695,-9.9796 9.9568,3.5229 -0.02105,9.9613 z"
|
||||
id="path52"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
style="color:#000000;fill:#ef2929;stroke:#650707;stroke-width:0.8;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
d="m 30.429192,16.964949 a 1.05,1.05 0 0 0 -1.326172,0.669921 1.05,1.05 0 0 0 0.671875,1.324219 l 1.996094,0.654297 a 1.05,1.05 0 0 0 1.324218,-0.669922 1.05,1.05 0 0 0 -0.671875,-1.324219 z m 4.988281,1.634765 a 1.05,1.05 0 0 0 -1.324219,0.669922 1.05,1.05 0 0 0 0.669922,1.326172 l 1.996094,0.654297 a 1.05,1.05 0 0 0 1.324219,-0.671875 1.05,1.05 0 0 0 -0.669922,-1.324219 z m 4.988281,1.636719 a 1.05,1.05 0 0 0 -1.324218,0.669922 1.05,1.05 0 0 0 0.669921,1.324218 l 1.996094,0.654297 A 1.05,1.05 0 0 0 43.07177,22.214948 1.05,1.05 0 0 0 42.401848,20.89073 Z m 4.988282,1.634765 a 1.05,1.05 0 0 0 -1.324219,0.669922 1.05,1.05 0 0 0 0.669922,1.326172 l 1.996093,0.654297 a 1.05,1.05 0 0 0 1.324219,-0.671875 1.05,1.05 0 0 0 -0.669922,-1.324219 z"
|
||||
id="path5" />
|
||||
<g
|
||||
id="g943"
|
||||
transform="matrix(0.72287451,0,0,0.72287451,-24.111096,5.1869402)">
|
||||
<path
|
||||
d="m 91,33.5 -0.02739,-14.214 12.967,4.3352 v 14.5 z"
|
||||
id="path54"
|
||||
style="fill:url(#linearGradient69709);stroke:#0b1521;stroke-width:2;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 92.927,32.029 0.04731,-10.141 8.9272,3.29 0.0781,10.042 z"
|
||||
id="path56"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2" />
|
||||
<path
|
||||
d="m 103.94,38.121 v -14.5 l 11,-9 L 115,28 Z"
|
||||
id="path58"
|
||||
style="fill:url(#linearGradient69717);stroke:#0b1521;stroke-width:2;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 105.94,33.621 v -9 l 7,-6 -0.0122,8.5816 z"
|
||||
id="path60"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2" />
|
||||
<path
|
||||
d="M 90.973,19.286 102,9.9998 l 12.94,4.6214 -11,9 z"
|
||||
id="path62"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#729fcf;stroke:#0b1521;stroke-width:2;stroke-linejoin:round" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,733 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
width="64"
|
||||
height="64"
|
||||
version="1.1"
|
||||
viewBox="0 0 64 64"
|
||||
id="svg96"
|
||||
sodipodi:docname="Assembly_ExplodedViewGroup.svg"
|
||||
inkscape:version="1.1-beta1 (77e7b44db3, 2021-03-28)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="3840"
|
||||
inkscape:window-height="1571"
|
||||
id="namedview98"
|
||||
showgrid="false"
|
||||
inkscape:zoom="3.6875"
|
||||
inkscape:cx="8.2711864"
|
||||
inkscape:cy="69.830508"
|
||||
inkscape:window-x="-9"
|
||||
inkscape:window-y="-9"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg96"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1" />
|
||||
<defs
|
||||
id="defs26">
|
||||
<linearGradient
|
||||
id="linearGradient1"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
style="stop-color:#efdc3d;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop1" />
|
||||
<stop
|
||||
style="stop-color:#bba80d;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4383">
|
||||
<stop
|
||||
stop-color="#3465a4"
|
||||
offset="0"
|
||||
id="stop2" />
|
||||
<stop
|
||||
stop-color="#729fcf"
|
||||
offset="1"
|
||||
id="stop4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4389"
|
||||
x1="20.244"
|
||||
x2="17.244"
|
||||
y1="37.588"
|
||||
y2="27.588"
|
||||
gradientTransform="translate(-1.2435,-2.5881)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient3774" />
|
||||
<linearGradient
|
||||
id="linearGradient4399"
|
||||
x1="48.714"
|
||||
x2="44.714"
|
||||
y1="45.586"
|
||||
y2="34.586"
|
||||
gradientTransform="translate(1.2856,1.4142)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="#c4a000"
|
||||
offset="0"
|
||||
id="stop8" />
|
||||
<stop
|
||||
stop-color="#edd400"
|
||||
offset="1"
|
||||
id="stop10" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient69042"
|
||||
x1="48.714"
|
||||
x2="44.714"
|
||||
y1="45.586"
|
||||
y2="34.586"
|
||||
gradientTransform="translate(-12.714,-17.586)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient3774" />
|
||||
<linearGradient
|
||||
id="linearGradient69056"
|
||||
x1="27.244"
|
||||
x2="22.244"
|
||||
y1="54.588"
|
||||
y2="40.588"
|
||||
gradientTransform="translate(-1.2435,-2.5881)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
stop-color="#c4a000"
|
||||
offset="0"
|
||||
id="stop14" />
|
||||
<stop
|
||||
stop-color="#fce94f"
|
||||
offset="1"
|
||||
id="stop16" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient69709"
|
||||
x1="20.244"
|
||||
x2="17.244"
|
||||
y1="37.588"
|
||||
y2="27.588"
|
||||
gradientTransform="matrix(1,-0.026667,0,1,81.696,-5.3735)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient4383" />
|
||||
<linearGradient
|
||||
id="linearGradient69717"
|
||||
x1="50.714"
|
||||
x2="48.714"
|
||||
y1="25.586"
|
||||
y2="20.586"
|
||||
gradientTransform="translate(61.2256,1.0356)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient4383" />
|
||||
<linearGradient
|
||||
id="linearGradient3774">
|
||||
<stop
|
||||
stop-color="#4e9a06"
|
||||
offset="0"
|
||||
id="stop21" />
|
||||
<stop
|
||||
stop-color="#8ae234"
|
||||
offset="1"
|
||||
id="stop23" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient69056"
|
||||
id="linearGradient920"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-41.2435,-2.5881)"
|
||||
x1="20.243999"
|
||||
y1="37.588001"
|
||||
x2="17.243999"
|
||||
y2="27.587999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4399"
|
||||
id="linearGradient922"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-52.714,-17.586)"
|
||||
x1="48.714001"
|
||||
y1="45.585999"
|
||||
x2="44.714001"
|
||||
y2="34.585999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient69056"
|
||||
id="linearGradient3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-1.2435,-2.5881)"
|
||||
x1="27.244"
|
||||
y1="54.588"
|
||||
x2="22.244"
|
||||
y2="40.588" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4399"
|
||||
id="linearGradient4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(1.2856,1.4142)"
|
||||
x1="48.714"
|
||||
y1="45.586"
|
||||
x2="44.714"
|
||||
y2="34.586" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1"
|
||||
id="linearGradient5"
|
||||
x1="8.000092"
|
||||
y1="31.5"
|
||||
x2="55.999914"
|
||||
y2="31.5"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
id="linearGradient6715"
|
||||
y2="609.51001"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="302.85999"
|
||||
gradientTransform="matrix(2.7744,0,0,1.9697,-1892.2,-872.89)"
|
||||
y1="366.64999"
|
||||
x1="302.85999">
|
||||
<stop
|
||||
id="stop5050"
|
||||
stop-opacity="0"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop5056"
|
||||
offset=".5" />
|
||||
<stop
|
||||
id="stop5052"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="radialGradient6717"
|
||||
xlink:href="#linearGradient5060"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cy="486.64999"
|
||||
cx="605.71002"
|
||||
gradientTransform="matrix(2.7744,0,0,1.9697,-1891.6,-872.89)"
|
||||
r="117.14" />
|
||||
<linearGradient
|
||||
id="linearGradient5060">
|
||||
<stop
|
||||
id="stop5062"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop5064"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
id="radialGradient6719"
|
||||
xlink:href="#linearGradient5060"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cy="486.64999"
|
||||
cx="605.71002"
|
||||
gradientTransform="matrix(-2.7744,0,0,1.9697,112.76,-872.89)"
|
||||
r="117.14" />
|
||||
<radialGradient
|
||||
id="radialGradient238"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
cy="37.518002"
|
||||
cx="20.705999"
|
||||
gradientTransform="matrix(1.055,-0.027345,0.1777,1.1909,-3.5722,-7.1253)"
|
||||
r="30.905001">
|
||||
<stop
|
||||
id="stop1790"
|
||||
stop-color="#202020"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop1791"
|
||||
stop-color="#b9b9b9"
|
||||
offset="1" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3104"
|
||||
y2="6.1803002"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="15.515"
|
||||
y1="31.368"
|
||||
x1="18.113001">
|
||||
<stop
|
||||
id="stop3098"
|
||||
stop-color="#424242"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop3100"
|
||||
stop-color="#777"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient491"
|
||||
y2="66.834"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="9.8980999"
|
||||
gradientTransform="matrix(1.5168,0,0,0.70898,-0.87957,-1.3182)"
|
||||
y1="13.773"
|
||||
x1="6.2298002">
|
||||
<stop
|
||||
id="stop3984"
|
||||
stop-color="#fff"
|
||||
stop-opacity=".87629"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop3985"
|
||||
stop-color="#fffffe"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient9772"
|
||||
y2="32.049999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="22.065001"
|
||||
y1="36.987999"
|
||||
x1="22.176001">
|
||||
<stop
|
||||
id="stop9768"
|
||||
stop-color="#6194cb"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop9770"
|
||||
stop-color="#729fcf"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient322"
|
||||
y2="46.688999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="12.854"
|
||||
gradientTransform="matrix(1.3175,0,0,0.81626,-0.87957,-1.3182)"
|
||||
y1="32.567001"
|
||||
x1="13.036">
|
||||
<stop
|
||||
id="stop320"
|
||||
stop-color="#fff"
|
||||
offset="0" />
|
||||
<stop
|
||||
id="stop321"
|
||||
stop-color="#fff"
|
||||
stop-opacity="0"
|
||||
offset="1" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata28">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>Path-Stock</dc:title>
|
||||
<dc:date>2015-07-04</dc:date>
|
||||
<dc:relation>https://www.freecad.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/Path/Gui/Resources/icons/Path-Stock.svg</dc:identifier>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>[agryson] Alexander Gryson</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
transform="matrix(1.4007339,0,0,1.4007339,-0.57832854,-1.5479608)">
|
||||
<g
|
||||
id="g6707"
|
||||
transform="matrix(0.022624,0,0,0.020868,43.383,36.37)">
|
||||
<rect
|
||||
id="rect6709"
|
||||
opacity="0.40206"
|
||||
height="478.35999"
|
||||
width="1339.6"
|
||||
y="-150.7"
|
||||
x="-1559.3"
|
||||
fill="url(#linearGradient6715)"
|
||||
style="fill:url(#linearGradient6715)" />
|
||||
<path
|
||||
id="path6711"
|
||||
opacity="0.40206"
|
||||
d="m -219.62,-150.68 v 478.33 c 142.88,0.9 345.4,-107.17 345.4,-239.2 0,-132.02 -159.44,-239.13 -345.4,-239.13 z"
|
||||
fill="url(#radialGradient6717)"
|
||||
style="fill:url(#radialGradient6717)" />
|
||||
<path
|
||||
id="path6713"
|
||||
opacity="0.40206"
|
||||
d="m -1559.3,-150.68 v 478.33 c -142.8,0.9 -345.4,-107.17 -345.4,-239.2 0,-132.02 159.5,-239.13 345.4,-239.13 z"
|
||||
fill="url(#radialGradient6719)"
|
||||
style="fill:url(#radialGradient6719)" />
|
||||
</g>
|
||||
<path
|
||||
id="path216"
|
||||
stroke-linejoin="round"
|
||||
d="m 4.5218,38.687 c 0.0218,0.417 0.4599,0.833 0.8762,0.833 h 31.327 c 0.416,0 0.811,-0.416 0.789,-0.833 L 36.578,11.461 c -0.022,-0.417 -0.46,-0.833 -0.877,-0.833 h -13.27 c -0.486,0 -1.235,-0.316 -1.402,-1.1066 L 20.417,6.6284 C 20.262,5.8927 19.535,5.5905 19.119,5.5905 H 4.34 c -0.4162,0 -0.8107,0.4163 -0.7889,0.8326 l 0.9707,32.264 z"
|
||||
stroke="url(#linearGradient3104)"
|
||||
stroke-linecap="round"
|
||||
fill="url(#radialGradient238)"
|
||||
style="fill:url(#radialGradient238);stroke:url(#linearGradient3104)" />
|
||||
<path
|
||||
id="path9788"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.2266,22.562 h 30.265"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9784"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.0422,18.562 h 30.447"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9778"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 4.9807,12.562 h 30.507"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9798"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.3862,32.562 h 30.109"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9800"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.5091,34.562 h 29.988"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9782"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.0422,16.562 h 30.447"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9780"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.0114,14.562 h 30.478"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9776"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 4.9221,10.562 h 15.281"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9774"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 4.8738,8.5625 h 14.783"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9794"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.3247,28.562 h 30.169"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9792"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.2881,26.562 h 30.205"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9790"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.2266,24.562 h 30.265"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9786"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.1959,20.562 h 30.296"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9796"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.3247,30.562 h 30.169"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path9802"
|
||||
opacity="0.11364"
|
||||
stroke-linejoin="round"
|
||||
d="m 5.5091,36.562 h 29.988"
|
||||
stroke="#000000"
|
||||
stroke-linecap="round"
|
||||
fill="#729fcf" />
|
||||
<path
|
||||
id="path219"
|
||||
opacity="0.45143"
|
||||
d="M 6.0683,38.864 C 6.0847,39.176 5.8874,39.384 5.5698,39.28 5.2521,39.176 5.033,38.968 5.0167,38.656 L 4.069,6.591 C 4.0526,6.2792 4.2341,6.0906 4.5464,6.0906 l 14.422,-0.0477 c 0.313,0 0.932,0.3005 1.133,1.3222 l 0.574,2.8159 c -0.427,-0.4656 -0.419,-0.48 -0.638,-1.1571 l -0.406,-1.2592 c -0.219,-0.7276 -0.698,-0.8319 -1.01,-0.8319 H 5.7334 c -0.3122,0 -0.5095,0.2082 -0.4931,0.5204 l 0.938,31.515 -0.1096,-0.104 z"
|
||||
display="block"
|
||||
fill="url(#linearGradient491)"
|
||||
style="fill:url(#linearGradient491)" />
|
||||
<g
|
||||
id="g220"
|
||||
fill-opacity="0.75706"
|
||||
transform="matrix(1.0408,0,0.054493,1.0408,-8.6702,2.6706)"
|
||||
fill="#ffffff">
|
||||
<path
|
||||
id="path221"
|
||||
fill-opacity="0.50847"
|
||||
fill="#ffffff"
|
||||
d="M 42.417,8.5152 C 42.422,8.4181 42.289,8.2682 42.182,8.2682 L 29.151,8.2661 c 0,0 0.911,0.5879 2.201,0.5962 l 11.054,0.071 c 0.011,-0.2117 0.003,-0.256 0.011,-0.4181 z" />
|
||||
</g>
|
||||
<path
|
||||
id="path233"
|
||||
stroke-linejoin="round"
|
||||
d="M 39.784,39.511 C 40.927,39.467 41.747,38.414 41.831,37.19 42.622,25.641 43.49,15.958 43.49,15.958 43.562,15.71 43.322,15.463 43.01,15.463 H 8.639 c -4e-4,0 -1.8507,21.867 -1.8507,21.867 -0.1145,0.982 -0.466,1.804 -1.5498,2.183 l 34.546,-0.002 z"
|
||||
display="block"
|
||||
stroke="#3465a4"
|
||||
fill="url(#linearGradient9772)"
|
||||
style="fill:url(#linearGradient9772)" />
|
||||
<path
|
||||
id="path304"
|
||||
opacity="0.46591"
|
||||
d="m 9.6202,16.464 32.791,0.065 -1.574,20.002 c -0.084,1.071 -0.45,1.428 -1.872,1.428 -1.872,0 -28.678,-0.032 -31.395,-0.032 0.2335,-0.321 0.3337,-0.989 0.335,-1.005 L 9.6204,16.464 Z"
|
||||
stroke="url(#linearGradient322)"
|
||||
stroke-linecap="round"
|
||||
stroke-width="1px"
|
||||
fill="none"
|
||||
style="stroke:url(#linearGradient322)" />
|
||||
<path
|
||||
id="path323"
|
||||
d="M 9.6202,16.223 8.4536,31.866 c 0,0 8.2964,-4.148 18.666,-4.148 10.3696,0 15.555,-11.495 15.555,-11.495 H 9.6196 Z"
|
||||
fill-opacity="0.089286"
|
||||
fill-rule="evenodd"
|
||||
fill="#ffffff" />
|
||||
</g>
|
||||
<g
|
||||
display="none"
|
||||
fill="#ef2929"
|
||||
fill-rule="evenodd"
|
||||
opacity="0.588"
|
||||
stroke="#ef2929"
|
||||
stroke-width="1px"
|
||||
id="g94">
|
||||
<path
|
||||
d="M 9,35 V 49"
|
||||
id="path66" />
|
||||
<path
|
||||
d="M 9,35 37,45"
|
||||
id="path68" />
|
||||
<path
|
||||
d="M 55,28 V 41"
|
||||
id="path70" />
|
||||
<path
|
||||
d="M 37,45 55,28"
|
||||
id="path72" />
|
||||
<path
|
||||
d="M 23,40 V 26"
|
||||
id="path74" />
|
||||
<path
|
||||
d="m 29,5 13,5"
|
||||
id="path76" />
|
||||
<path
|
||||
d="M 23,26 42,10"
|
||||
id="path78" />
|
||||
<path
|
||||
d="M 19,13 29,5"
|
||||
id="path80" />
|
||||
<path
|
||||
d="m 55,15 -9,8"
|
||||
id="path82" />
|
||||
<path
|
||||
d="M 42,23 V 10"
|
||||
id="path84" />
|
||||
<path
|
||||
d="m 42,23 14,5"
|
||||
id="path86" />
|
||||
<path
|
||||
d="M 23,40 42,23"
|
||||
id="path88" />
|
||||
<path
|
||||
d="M 23,10 H 42"
|
||||
id="path90" />
|
||||
<path
|
||||
d="M 34,17 V 30"
|
||||
id="path92" />
|
||||
</g>
|
||||
<g
|
||||
id="g40"
|
||||
style="stroke-width:2"
|
||||
transform="matrix(0.46760213,0,0,0.46760213,21.482179,26.152147)">
|
||||
<path
|
||||
d="M 9,49 V 35 l 28,10 v 14 z"
|
||||
id="path30"
|
||||
style="fill:url(#linearGradient3);stroke:#302b00;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 37,59 V 45 L 55,28 v 13 z"
|
||||
id="path32"
|
||||
style="fill:url(#linearGradient4);stroke:#302b00;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="M 11.008,47.606 11,37.9997 l 24,8 0.0081,10.185 z"
|
||||
id="path34"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#fce94f" />
|
||||
<path
|
||||
d="M 39.005,54.168 39,45.9998 l 14,-13 0.0021,7.1768 z"
|
||||
id="path36"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#edd400" />
|
||||
<path
|
||||
d="M 9,35 28,18 55,28 37,45 Z"
|
||||
id="path38"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient5);stroke:#302b00;stroke-linejoin:round"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
d="M 12.804336,34.208711 28.573658,19.940661 51.218486,28.771569 36.523799,42.772294 Z"
|
||||
id="path34-3"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
<path
|
||||
style="color:#000000;fill:#ef2929;stroke:#650707;stroke-width:0.465226;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
d="m 31.980628,30.946217 a 0.58153205,0.58153205 0 0 0 -0.581532,0.581532 l 0.0012,0.998372 a 0.58153205,0.58153205 0 0 0 0.582668,0.581532 0.58153205,0.58153205 0 0 0 0.580396,-0.582667 l -0.0012,-0.998373 a 0.58153205,0.58153205 0 0 0 -0.581532,-0.580396 z m 0.0023,2.742968 a 0.58153205,0.58153205 0 0 0 -0.581532,0.581532 l 0.0012,1.163065 a 0.58153205,0.58153205 0 0 0 0.582668,0.581532 0.58153205,0.58153205 0 0 0 0.580396,-0.582668 l -0.0012,-1.163064 a 0.58153205,0.58153205 0 0 0 -0.581532,-0.580397 z m 0.0023,2.907661 a 0.58153205,0.58153205 0 0 0 -0.580397,0.581532 v 1.163064 a 0.58153205,0.58153205 0 0 0 0.582668,0.581532 0.58153205,0.58153205 0 0 0 0.580397,-0.582668 v -1.163064 a 0.58153205,0.58153205 0 0 0 -0.582661,-0.580396 z m 0.0023,2.90766 a 0.58153205,0.58153205 0 0 0 -0.580397,0.581532 l 0.0012,1.163064 a 0.58153205,0.58153205 0 0 0 0.581533,0.581532 0.58153205,0.58153205 0 0 0 0.581532,-0.582668 l -0.0012,-1.163064 a 0.58153205,0.58153205 0 0 0 -0.582658,-0.580396 z"
|
||||
id="path6" />
|
||||
<g
|
||||
id="g963"
|
||||
transform="matrix(0.46760213,0,0,0.46760213,35.430185,19.505223)">
|
||||
<g
|
||||
style="stroke:#172a04;stroke-width:2;stroke-linejoin:round"
|
||||
transform="translate(-40)"
|
||||
id="g48">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient4389)"
|
||||
id="path42"
|
||||
d="M 9,35 V 21 l 14,5 v 14 z" />
|
||||
<path
|
||||
style="fill:#8ae234"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path44"
|
||||
d="M 9,21 28.585,5.209 42,10.0001 l -19,16 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient69042)"
|
||||
id="path46"
|
||||
d="M 23,40 V 26 l 7.9726,-6.7138 0.02739,13.714 z" />
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient920);fill-opacity:1;stroke:#172a04;stroke-width:2;stroke-linejoin:round"
|
||||
id="path912"
|
||||
d="M -31,35 V 21 l 14,5 v 14 z" />
|
||||
<path
|
||||
style="fill:#fce94f;fill-opacity:1;stroke:#172a04;stroke-width:2;stroke-linejoin:round;stroke-opacity:1"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path914"
|
||||
d="M -31,21 -11.415,5.209 2,10.0001 l -19,16 z" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:url(#linearGradient922);fill-opacity:1;stroke:#172a04;stroke-width:2;stroke-linejoin:round"
|
||||
id="path916"
|
||||
d="M -17,40 V 26 L 2,10.0001 2.0000003,23 Z"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
d="m -15,35.578425 v -9 L 0.08743031,14.309658 0.2139029,22.129247 Z"
|
||||
id="path50"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
d="m -29.049,33.746 0.08695,-9.9796 9.9568,3.5229 -0.02105,9.9613 z"
|
||||
id="path52"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#fce94f;stroke-width:2;stroke-opacity:1" />
|
||||
</g>
|
||||
<path
|
||||
style="color:#000000;fill:#ef2929;stroke:#650707;stroke-width:0.465226;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:normal"
|
||||
d="m 35.371337,28.780985 a 0.61060865,0.61060865 0 0 0 -0.771211,0.38958 0.61060865,0.61060865 0 0 0 0.390717,0.770076 l 1.160792,0.380495 a 0.61060865,0.61060865 0 0 0 0.770076,-0.389582 0.61060865,0.61060865 0 0 0 -0.390717,-0.770075 z m 2.900846,0.950668 a 0.61060865,0.61060865 0 0 0 -0.770076,0.389581 0.61060865,0.61060865 0 0 0 0.389581,0.771211 l 1.160793,0.380495 a 0.61060865,0.61060865 0 0 0 0.770075,-0.390717 0.61060865,0.61060865 0 0 0 -0.389581,-0.770076 z m 2.900845,0.951804 a 0.61060865,0.61060865 0 0 0 -0.770075,0.389581 0.61060865,0.61060865 0 0 0 0.38958,0.770076 l 1.160793,0.380494 a 0.61060865,0.61060865 0 0 0 0.770076,-0.389581 0.61060865,0.61060865 0 0 0 -0.389581,-0.770075 z m 2.900846,0.950669 a 0.61060865,0.61060865 0 0 0 -0.770076,0.389581 0.61060865,0.61060865 0 0 0 0.389581,0.771211 l 1.160792,0.380495 a 0.61060865,0.61060865 0 0 0 0.770076,-0.390717 0.61060865,0.61060865 0 0 0 -0.389581,-0.770076 z"
|
||||
id="path5" />
|
||||
<g
|
||||
id="g943"
|
||||
transform="matrix(0.4203747,0,0,0.4203747,4.6035649,21.524915)">
|
||||
<path
|
||||
d="m 91,33.5 -0.02739,-14.214 12.967,4.3352 v 14.5 z"
|
||||
id="path54"
|
||||
style="fill:url(#linearGradient69709);stroke:#0b1521;stroke-width:2;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 92.927,32.029 0.04731,-10.141 8.9272,3.29 0.0781,10.042 z"
|
||||
id="path56"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2" />
|
||||
<path
|
||||
d="m 103.94,38.121 v -14.5 l 11,-9 L 115,28 Z"
|
||||
id="path58"
|
||||
style="fill:url(#linearGradient69717);stroke:#0b1521;stroke-width:2;stroke-linejoin:round"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 105.94,33.621 v -9 l 7,-6 -0.0122,8.5816 z"
|
||||
id="path60"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#729fcf;stroke-width:2" />
|
||||
<path
|
||||
d="M 90.973,19.286 102,9.9998 l 12.94,4.6214 -11,9 z"
|
||||
id="path62"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#729fcf;stroke:#0b1521;stroke-width:2;stroke-linejoin:round" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 24 KiB |
@@ -0,0 +1,73 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TaskAssemblyCreateView</class>
|
||||
<widget class="QWidget" name="TaskAssemblyCreateView">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>376</width>
|
||||
<height>387</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Create Exploded View</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="Gui::PrefCheckBox" name="CheckBox_PartsAsSingleSolid">
|
||||
<property name="toolTip">
|
||||
<string>If checked, Parts will be selected as a single solid.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Parts as single solid</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>PartsAsSingleSolid</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Assembly</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QListWidget" name="stepList"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QPushButton" name="btnAlignDragger">
|
||||
<property name="text">
|
||||
<string>Align dragger</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="LabelAlignDragger">
|
||||
<property name="text">
|
||||
<string>Aligning dragger:
|
||||
Select a feature.
|
||||
Press ESC to cancel.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QPushButton" name="btnRadialExplosion">
|
||||
<property name="text">
|
||||
<string>Explode radially</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Gui::PrefCheckBox</class>
|
||||
<extends>QCheckBox</extends>
|
||||
<header>Gui/PrefWidgets.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -0,0 +1,49 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <[email protected]> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#endif
|
||||
|
||||
#include <App/Document.h>
|
||||
#include <App/DocumentObject.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
|
||||
#include "ViewProviderViewGroup.h"
|
||||
|
||||
|
||||
using namespace AssemblyGui;
|
||||
|
||||
PROPERTY_SOURCE(AssemblyGui::ViewProviderViewGroup, Gui::ViewProviderDocumentObjectGroup)
|
||||
|
||||
ViewProviderViewGroup::ViewProviderViewGroup()
|
||||
{}
|
||||
|
||||
ViewProviderViewGroup::~ViewProviderViewGroup() = default;
|
||||
|
||||
QIcon ViewProviderViewGroup::getIcon() const
|
||||
{
|
||||
return Gui::BitmapFactory().pixmap("Assembly_ExplodedViewGroup.svg");
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
/****************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2023 Ondsel <[email protected]> *
|
||||
* *
|
||||
* This file is part of FreeCAD. *
|
||||
* *
|
||||
* FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
* under the terms of the GNU Lesser General Public License as *
|
||||
* published by the Free Software Foundation, either version 2.1 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* FreeCAD 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 *
|
||||
* Lesser General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Lesser General Public *
|
||||
* License along with FreeCAD. If not, see *
|
||||
* <https://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef ASSEMBLYGUI_VIEWPROVIDER_ViewProviderViewGroup_H
|
||||
#define ASSEMBLYGUI_VIEWPROVIDER_ViewProviderViewGroup_H
|
||||
|
||||
#include <Mod/Assembly/AssemblyGlobal.h>
|
||||
|
||||
#include <Gui/ViewProviderDocumentObjectGroup.h>
|
||||
|
||||
|
||||
namespace AssemblyGui
|
||||
{
|
||||
|
||||
class AssemblyGuiExport ViewProviderViewGroup: public Gui::ViewProviderDocumentObjectGroup
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(AssemblyGui::ViewProviderViewGroup);
|
||||
|
||||
public:
|
||||
ViewProviderViewGroup();
|
||||
~ViewProviderViewGroup() override;
|
||||
|
||||
/// deliver the icon shown in the tree view. Override from ViewProvider.h
|
||||
QIcon getIcon() const override;
|
||||
|
||||
// Prevent dragging of the joints and dropping things inside the joint group.
|
||||
bool canDragObjects() const override
|
||||
{
|
||||
return false;
|
||||
};
|
||||
bool canDropObjects() const override
|
||||
{
|
||||
return false;
|
||||
};
|
||||
bool canDragAndDropObject(App::DocumentObject*) const override
|
||||
{
|
||||
return false;
|
||||
};
|
||||
|
||||
// protected:
|
||||
/// get called by the container whenever a property has been changed
|
||||
// void onChanged(const App::Property* prop) override;
|
||||
};
|
||||
|
||||
} // namespace AssemblyGui
|
||||
|
||||
#endif // ASSEMBLYGUI_VIEWPROVIDER_ViewProviderViewGroup_H
|
||||
@@ -63,7 +63,7 @@ class AssemblyWorkbench(Workbench):
|
||||
# load the builtin modules
|
||||
from PySide import QtCore, QtGui
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP
|
||||
import CommandCreateAssembly, CommandInsertLink, CommandCreateJoint, CommandSolveAssembly, CommandExportASMT
|
||||
import CommandCreateAssembly, CommandInsertLink, CommandCreateJoint, CommandSolveAssembly, CommandExportASMT, CommandCreateView
|
||||
from Preferences import PreferencesPage
|
||||
|
||||
# from Preferences import preferences
|
||||
@@ -78,6 +78,7 @@ class AssemblyWorkbench(Workbench):
|
||||
"Assembly_CreateAssembly",
|
||||
"Assembly_InsertLink",
|
||||
"Assembly_SolveAssembly",
|
||||
"Assembly_CreateView",
|
||||
]
|
||||
|
||||
cmdListMenuOnly = [
|
||||
|
||||
@@ -603,6 +603,20 @@ def getJointGroup(assembly):
|
||||
return joint_group
|
||||
|
||||
|
||||
def getViewGroup(assembly):
|
||||
view_group = None
|
||||
|
||||
for obj in assembly.OutList:
|
||||
if obj.TypeId == "Assembly::ViewGroup":
|
||||
view_group = obj
|
||||
break
|
||||
|
||||
if not view_group:
|
||||
view_group = assembly.newObject("Assembly::ViewGroup", "Exploded Views")
|
||||
|
||||
return view_group
|
||||
|
||||
|
||||
def isAssemblyGrounded():
|
||||
assembly = activeAssembly()
|
||||
if not assembly:
|
||||
|
||||
Reference in New Issue
Block a user