TechDraw: Extended Draft View

This commit is contained in:
Yorik van Havre 2016-09-14 12:38:34 -03:00
parent fb9fb9873f
commit d8ebfe58c5
7 changed files with 130 additions and 50 deletions

View File

@ -1712,12 +1712,20 @@ def getDXF(obj,direction=None):
return result return result
def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direction=None,linestyle=None,color=None,linespacing=None): def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direction=None,linestyle=None,color=None,linespacing=None,techdraw=False):
'''getSVG(object,[scale], [linewidth],[fontsize],[fillstyle],[direction],[linestyle],[color],[linespacing]): '''getSVG(object,[scale], [linewidth],[fontsize],[fillstyle],[direction],[linestyle],[color],[linespacing]):
returns a string containing a SVG representation of the given object, returns a string containing a SVG representation of the given object,
with the given linewidth and fontsize (used if the given object contains with the given linewidth and fontsize (used if the given object contains
any text). You can also supply an arbitrary projection vector. the any text). You can also supply an arbitrary projection vector. the
scale parameter allows to scale linewidths down, so they are resolution-independant.''' scale parameter allows to scale linewidths down, so they are resolution-independant.'''
# if this is a group, gather all the svg views of its children
if obj.isDerivedFrom("App::DocumentObjectGroup"):
svg = ""
for child in obj.Group:
svg += getSVG(child,scale,linewidth,fontsize,fillstyle,direction,linestyle,color,linespacing,techdraw)
return svg
import Part, DraftGeomUtils import Part, DraftGeomUtils
pathdata = [] pathdata = []
svg = "" svg = ""
@ -1739,7 +1747,10 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct
plane = direction plane = direction
stroke = "#000000" stroke = "#000000"
if color: if color:
stroke = getrgb(color) if "#" in color:
stroke = color
else:
stroke = getrgb(color)
elif gui: elif gui:
if hasattr(obj.ViewObject,"LineColor"): if hasattr(obj.ViewObject,"LineColor"):
stroke = getrgb(obj.ViewObject.LineColor) stroke = getrgb(obj.ViewObject.LineColor)
@ -1754,12 +1765,18 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct
l = p.GetString("svgDashdotLine","0.09,0.05,0.02,0.05") l = p.GetString("svgDashdotLine","0.09,0.05,0.02,0.05")
elif linestyle == "Dotted": elif linestyle == "Dotted":
l = p.GetString("svgDottedLine","0.02,0.02") l = p.GetString("svgDottedLine","0.02,0.02")
elif "," in linestyle:
l = linestyle
if l: if l:
l = l.split(",") l = l.split(",")
# scale dashes try:
l = ",".join([str(float(d)/scale) for d in l]) # scale dashes
#print "lstyle ",l l = ",".join([str(float(d)/scale) for d in l])
return l #print "lstyle ",l
except:
return "none"
else:
return l
return "none" return "none"
def getProj(vec): def getProj(vec):
@ -1770,6 +1787,8 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct
ny = DraftVecUtils.project(vec,plane.v) ny = DraftVecUtils.project(vec,plane.v)
ly = ny.Length ly = ny.Length
if abs(ny.getAngle(plane.v)) > 0.1: ly = -ly if abs(ny.getAngle(plane.v)) > 0.1: ly = -ly
if techdraw:
ly = -ly
return Vector(lx,ly,0) return Vector(lx,ly,0)
def getPattern(pat): def getPattern(pat):
@ -1972,41 +1991,53 @@ def getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direct
anchor = "start" anchor = "start"
else: else:
anchor = "end" anchor = "end"
svg = '<text fill="' if techdraw:
svg += color +'" font-size="' svg = ""
svg += str(fontsize) + '" '
svg += 'style="text-anchor:'+anchor+';text-align:'+align.lower()+';'
svg += 'font-family:'+ fontname +'" '
svg += 'transform="rotate('+str(math.degrees(angle))
svg += ','+ str(base.x) + ',' + str(base.y) + ') '
if flip:
svg += 'translate(' + str(base.x) + ',' + str(base.y) + ') '
else:
svg += 'translate(' + str(base.x) + ',' + str(-base.y) + ') '
#svg += 'scale('+str(tmod/2000)+',-'+str(tmod/2000)+') '
if flip:
svg += 'scale(1,-1) '
else:
svg += 'scale(1,1) '
svg += '" freecad:skip="1"'
svg += '>\n'
if len(text) == 1:
try:
svg += text[0]
except:
svg += text[0].decode("utf8")
else:
for i in range(len(text)): for i in range(len(text)):
if i == 0: svg += '<text fill="' + color +'" font-size="' + str(fontsize) + '" '
svg += '<tspan>' svg += 'style="text-anchor:'+anchor+';text-align:'+align.lower()+';'
else: svg += 'font-family:'+ fontname +'" '
svg += '<tspan x="0" dy="'+str(linespacing)+'">' svg += 'transform="rotate('+str(math.degrees(angle))
svg += ','+ str(base.x) + ',' + str(base.y+linespacing*i) + ') '
svg += 'translate(' + str(base.x) + ',' + str(base.y+linespacing*i) + ') '
svg += '" freecad:skip="1"'
svg += '>\n' + text[i] + '</text>\n'
else:
svg = '<text fill="'
svg += color +'" font-size="'
svg += str(fontsize) + '" '
svg += 'style="text-anchor:'+anchor+';text-align:'+align.lower()+';'
svg += 'font-family:'+ fontname +'" '
svg += 'transform="rotate('+str(math.degrees(angle))
svg += ','+ str(base.x) + ',' + str(base.y) + ') '
if flip:
svg += 'translate(' + str(base.x) + ',' + str(base.y) + ') '
else:
svg += 'translate(' + str(base.x) + ',' + str(-base.y) + ') '
#svg += 'scale('+str(tmod/2000)+',-'+str(tmod/2000)+') '
if flip and (not techdraw):
svg += 'scale(1,-1) '
else:
svg += 'scale(1,1) '
svg += '" freecad:skip="1"'
svg += '>\n'
if len(text) == 1:
try: try:
svg += text[i] svg += text[0]
except: except:
svg += text[i].decode("utf8") svg += text[0].decode("utf8")
svg += '</tspan>\n' else:
svg += '</text>\n' for i in range(len(text)):
if i == 0:
svg += '<tspan>'
else:
svg += '<tspan x="0" dy="'+str(linespacing)+'">'
try:
svg += text[i]
except:
svg += text[i].decode("utf8")
svg += '</tspan>\n'
svg += '</text>\n'
return svg return svg

View File

@ -52,8 +52,12 @@ DrawViewDraft::DrawViewDraft(void)
static const char *group = "Draft view"; static const char *group = "Draft view";
ADD_PROPERTY_TYPE(Source ,(0),group,App::Prop_None,"Draft object for this view"); ADD_PROPERTY_TYPE(Source ,(0),group,App::Prop_None,"Draft object for this view");
ADD_PROPERTY_TYPE(LineScale,(1.0),group,App::Prop_None,"Line width adjustment factor for this view"); ADD_PROPERTY_TYPE(LineWidth,(0.35),group,App::Prop_None,"Line width of this view");
ADD_PROPERTY_TYPE(FontSize,(12.0),group,App::Prop_None,"Text size for this view"); ADD_PROPERTY_TYPE(FontSize,(12.0),group,App::Prop_None,"Text size for this view");
ADD_PROPERTY_TYPE(Direction ,(0,0,1.0),group,App::Prop_None,"Projection direction. The direction you are looking from.");
ADD_PROPERTY_TYPE(Color,(0.0f,0.0f,0.0f),group,App::Prop_None,"The default color of text and lines");
ADD_PROPERTY_TYPE(LineStyle,("Solid") ,group,App::Prop_None,"A line style to use for this view. Can be Solid, Dashed, Dashdot, Dot or a SVG pattern like 0.20,0.20");
ADD_PROPERTY_TYPE(LineSpacing,(1.0f),group,App::Prop_None,"The spacing between lines to use for multiline texts");
ScaleType.setValue("Custom"); ScaleType.setValue("Custom");
} }
@ -65,8 +69,12 @@ void DrawViewDraft::onChanged(const App::Property* prop)
{ {
if (!isRestoring()) { if (!isRestoring()) {
if (prop == &Source || if (prop == &Source ||
prop == &LineScale || prop == &LineWidth ||
prop == &FontSize) { prop == &FontSize ||
prop == &Direction ||
prop == &Color ||
prop == &LineStyle ||
prop == &LineSpacing) {
try { try {
App::DocumentObjectExecReturn *ret = recompute(); App::DocumentObjectExecReturn *ret = recompute();
delete ret; delete ret;
@ -87,9 +95,20 @@ App::DocumentObjectExecReturn *DrawViewDraft::execute(void)
std::string svgTail = getSVGTail(); std::string svgTail = getSVGTail();
std::string FeatName = getNameInDocument(); std::string FeatName = getNameInDocument();
std::string SourceName = sourceObj->getNameInDocument(); std::string SourceName = sourceObj->getNameInDocument();
// Draft.getSVG(obj,scale=1,linewidth=0.35,fontsize=12,fillstyle="shape color",direction=None,linestyle=None,color=None,linespacing=None,techdraw=False)
std::stringstream paramStr; std::stringstream paramStr;
paramStr << ",scale=" << LineScale.getValue() << ",fontsize=" << FontSize.getValue(); App::Color col = Color.getValue();
paramStr << ",scale=" << Scale.getValue()
<< ",linewidth=" << LineWidth.getValue()
<< ",fontsize=" << FontSize.getValue()
// TODO treat fillstyle here
<< ",direction=FreeCAD.Vector(" << Direction.getValue().x << "," << Direction.getValue().y << "," << Direction.getValue().z << ")"
<< ",linestyle=\"" << LineStyle.getValue() << "\""
<< ",color=\"" << col.asCSSString() << "\""
<< ",linespacing=" << LineSpacing.getValue()
// We must set techdraw to "true" becausea couple of things behave differently than in Drawing
<< ",techdraw=True";
// this is ok for a starting point, but should eventually make dedicated Draft functions that build the svg for all the special cases // this is ok for a starting point, but should eventually make dedicated Draft functions that build the svg for all the special cases
// (Arch section, etc) // (Arch section, etc)
@ -124,7 +143,7 @@ namespace App {
/// @cond DOXERR /// @cond DOXERR
PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawViewDraftPython, TechDraw::DrawViewDraft) PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawViewDraftPython, TechDraw::DrawViewDraft)
template<> const char* TechDraw::DrawViewDraftPython::getViewProviderName(void) const { template<> const char* TechDraw::DrawViewDraftPython::getViewProviderName(void) const {
return "TechDrawGui::ViewProviderSymbol"; return "TechDrawGui::ViewProviderDraft";
} }
/// @endcond /// @endcond

View File

@ -44,8 +44,12 @@ public:
virtual ~DrawViewDraft(); virtual ~DrawViewDraft();
App::PropertyLink Source; App::PropertyLink Source;
App::PropertyFloat LineScale; App::PropertyFloat LineWidth;
App::PropertyFloat FontSize; App::PropertyFloat FontSize;
App::PropertyVector Direction;
App::PropertyColor Color;
App::PropertyString LineStyle;
App::PropertyFloat LineSpacing;
/** @name methods overide Feature */ /** @name methods overide Feature */
//@{ //@{
@ -55,7 +59,7 @@ public:
/// returns the type name of the ViewProvider /// returns the type name of the ViewProvider
virtual const char* getViewProviderName(void) const { virtual const char* getViewProviderName(void) const {
return "TechDrawGui::ViewProviderSymbol"; return "TechDrawGui::ViewProviderDraft";
} }
protected: protected:

View File

@ -96,6 +96,7 @@ void TechDrawGuiExport initTechDrawGui()
TechDrawGui::ViewProviderViewClip::init(); TechDrawGui::ViewProviderViewClip::init();
TechDrawGui::ViewProviderAnnotation::init(); TechDrawGui::ViewProviderAnnotation::init();
TechDrawGui::ViewProviderSymbol::init(); TechDrawGui::ViewProviderSymbol::init();
TechDrawGui::ViewProviderDraft::init();
TechDrawGui::ViewProviderHatch::init(); TechDrawGui::ViewProviderHatch::init();
TechDrawGui::ViewProviderSpreadsheet::init(); TechDrawGui::ViewProviderSpreadsheet::init();

View File

@ -790,16 +790,15 @@ void CmdTechDrawDraftView::activated(int iMsg)
return; return;
} }
std::vector<App::DocumentObject*> shapes = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); std::vector<App::DocumentObject*> objects = getSelection().getObjectsOfType(App::DocumentObject::getClassTypeId());
if (shapes.empty()) { if (objects.empty()) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Select at least 1 Part object.")); QObject::tr("Select at least one object."));
return; return;
} }
std::string PageName = page->getNameInDocument(); std::string PageName = page->getNameInDocument();
std::string SourceName = shapes.front()->getNameInDocument();
for (std::vector<App::DocumentObject*>::iterator it = shapes.begin(); it != shapes.end(); ++it) { for (std::vector<App::DocumentObject*>::iterator it = objects.begin(); it != objects.end(); ++it) {
std::string FeatName = getUniqueObjectName("DraftView"); std::string FeatName = getUniqueObjectName("DraftView");
std::string SourceName = (*it)->getNameInDocument(); std::string SourceName = (*it)->getNameInDocument();
openCommand("Create DraftView"); openCommand("Create DraftView");

View File

@ -84,3 +84,18 @@ TechDraw::DrawViewSymbol* ViewProviderSymbol::getViewObject() const
{ {
return dynamic_cast<TechDraw::DrawViewSymbol*>(pcObject); return dynamic_cast<TechDraw::DrawViewSymbol*>(pcObject);
} }
//**************************************************************************
// Draft view
PROPERTY_SOURCE(TechDrawGui::ViewProviderDraft, TechDrawGui::ViewProviderSymbol)
ViewProviderDraft::ViewProviderDraft()
{
sPixmap = "actions/techdraw-draft-view.svg";
}
ViewProviderDraft::~ViewProviderDraft()
{
}

View File

@ -54,6 +54,17 @@ public:
virtual TechDraw::DrawViewSymbol* getViewObject() const; virtual TechDraw::DrawViewSymbol* getViewObject() const;
}; };
class TechDrawGuiExport ViewProviderDraft : public ViewProviderSymbol
{
PROPERTY_HEADER(TechDrawGui::ViewProviderDraft);
public:
/// constructor
ViewProviderDraft();
/// destructor
virtual ~ViewProviderDraft();
};
} // namespace TechDrawGui } // namespace TechDrawGui