Initial working version of geometric crosshatch/PAT files

This commit is contained in:
WandererFan
2017-01-13 10:31:51 -05:00
parent 974032dd91
commit 33479bd4e3
35 changed files with 1826 additions and 74 deletions

View File

@@ -31,6 +31,7 @@
#include "DrawViewSymbol.h"
#include "DrawViewClip.h"
#include "DrawHatch.h"
#include "DrawCrosshatch.h"
#include "DrawViewDraft.h"
#include "DrawViewArch.h"
#include "DrawViewSpreadsheet.h"
@@ -84,6 +85,7 @@ PyMODINIT_FUNC initTechDraw()
TechDraw::DrawViewClip ::init();
TechDraw::DrawHatch ::init();
TechDraw::DrawCrosshatch ::init();
TechDraw::DrawViewDraft ::init();
TechDraw::DrawViewArch ::init();
TechDraw::DrawViewImage ::init();

View File

@@ -37,6 +37,7 @@ generate_from_xml(DrawViewSymbolPy)
generate_from_xml(DrawViewClipPy)
generate_from_xml(DrawViewDimensionPy)
generate_from_xml(DrawHatchPy)
generate_from_xml(DrawCrosshatchPy)
generate_from_xml(DrawViewCollectionPy)
generate_from_xml(DrawProjGroupPy)
generate_from_xml(DrawProjGroupItemPy)
@@ -74,6 +75,8 @@ SET(Draw_SRCS
DrawViewSection.h
DrawHatch.cpp
DrawHatch.h
DrawCrosshatch.cpp
DrawCrosshatch.h
DrawViewDraft.cpp
DrawViewDraft.h
DrawViewArch.cpp
@@ -92,6 +95,8 @@ SET(TechDraw_SRCS
DrawUtil.h
Cube.cpp
Cube.h
HatchLine.cpp
HatchLine.h
PreCompiled.cpp
PreCompiled.h
EdgeWalker.cpp
@@ -128,6 +133,8 @@ SET(Python_SRCS
DrawViewDimensionPyImp.cpp
DrawHatchPy.xml
DrawHatchPyImp.cpp
DrawCrosshatchPy.xml
DrawCrosshatchPyImp.cpp
DrawViewCollectionPy.xml
DrawViewCollectionPyImp.cpp
DrawProjGroupPy.xml

View File

@@ -0,0 +1,445 @@
/***************************************************************************
* Copyright (c) 2015 WandererFan <wandererfan@gmail.com> *
* *
* 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"
#ifndef _PreComp_
# include <sstream>
#include <iomanip>
#include <cmath>
# include <QFile>
# include <QFileInfo>
#include <gp_Pln.hxx>
#include <gp_Pnt.hxx>
#include <Bnd_Box.hxx>
#include <BRepBndLib.hxx>
#include <BRep_Builder.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <Standard_PrimitiveTypes.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_Compound.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopExp.hxx>
#endif
#include <App/Application.h>
#include <Base/Console.h>
#include <Base/Exception.h>
#include <Base/FileInfo.h>
#include <Base/Parameter.h>
#include "HatchLine.h"
#include "DrawUtil.h"
#include "Geometry.h"
#include "DrawViewPart.h"
#include "DrawCrosshatch.h"
#include <Mod/TechDraw/App/DrawCrosshatchPy.h> // generated from DrawCrosshatchPy.xml
using namespace TechDraw;
using namespace TechDrawGeometry;
using namespace std;
PROPERTY_SOURCE(TechDraw::DrawCrosshatch, App::DocumentObject)
DrawCrosshatch::DrawCrosshatch(void)
{
static const char *vgroup = "Crosshatch";
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Colors");
App::Color fcColor;
fcColor.setPackedValue(hGrp->GetUnsigned("Crosshatch", 0x00000000));
ADD_PROPERTY_TYPE(DirProjection ,(0,0,1.0) ,vgroup,App::Prop_None,"Projection direction when Crosshatch was defined"); //sb RO?
ADD_PROPERTY_TYPE(Source,(0),vgroup,(App::PropertyType)(App::Prop_None),"The View + Face to be crosshatched");
ADD_PROPERTY_TYPE(FilePattern ,(""),vgroup,App::Prop_None,"The crosshatch pattern file for this area");
ADD_PROPERTY_TYPE(NamePattern,(""),vgroup,App::Prop_None,"The name of the pattern");
ADD_PROPERTY_TYPE(ScalePattern,(1.0),vgroup,App::Prop_None,"Crosshatch pattern size adjustment");
// ADD_PROPERTY_TYPE(ColorPattern,(fcColor),vgroup,App::Prop_None,"The color of the pattern"); //to vp?
// ADD_PROPERTY_TYPE(WeightPattern,(0.0),vgroup,App::Prop_None,"Crosshatch pattern line thickness");
// ADD_PROPERTY_TYPE(LineSpecs,(""),vgroup,App::Prop_None,"Pattern line specifications"); //this sb RO or removed?
DirProjection.setStatus(App::Property::ReadOnly,true);
//this is probably "/build/data/Mod/TechDraw/PAT"
hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/PAT");
std::string defaultDir = App::Application::getResourceDir() + "Mod/TechDraw/PAT/";
std::string defaultFileName = defaultDir + "FCStd.pat";
QString patternFileName = QString::fromStdString(hGrp->GetASCII("FilePattern",defaultFileName.c_str()));
if (patternFileName.isEmpty()) {
patternFileName = QString::fromStdString(defaultFileName);
}
QFileInfo tfi(patternFileName);
if (tfi.isReadable()) {
FilePattern.setValue(patternFileName.toUtf8().constData());
}
hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/PAT");
std::string defaultNamePattern = "Diamond";
NamePattern.setValue(hGrp->GetASCII("NamePattern",defaultNamePattern.c_str()));
}
DrawCrosshatch::~DrawCrosshatch()
{
}
void DrawCrosshatch::onChanged(const App::Property* prop)
{
if (prop == &Source ) {
if (!isRestoring()) {
DrawCrosshatch::execute();
}
}
if (prop == &FilePattern ||
prop == &NamePattern ) {
if ((!FilePattern.isEmpty()) &&
(!NamePattern.isEmpty())) {
std::vector<HatchLine> specs = getDecodedSpecsFromFile();
m_lineSets.clear();
for (auto& hl: specs) {
//hl.dump("hl from file");
LineSet ls;
ls.setHatchLine(hl);
m_lineSets.push_back(ls);
}
}
}
if (prop == &ScalePattern) {
if (!isRestoring()) {
adviseParent(); //just need to have the parent redraw on Gui side. handle through VPDC::updateData
}
}
App::DocumentObject::onChanged(prop);
}
short DrawCrosshatch::mustExecute() const
{
short result = 0;
if (!isRestoring()) {
result = (Source.isTouched() ||
FilePattern.isTouched() ||
NamePattern.isTouched() );
}
if (result) {
return result;
}
return App::DocumentObject::mustExecute();
}
App::DocumentObjectExecReturn *DrawCrosshatch::execute(void)
{
DrawViewPart* source = getSourceView();
if (!source) {
return App::DocumentObject::StdReturn;
}
if (!source->hasGeometry()) {
return App::DocumentObject::StdReturn;
}
Base::Vector3d sourceDir = source->Direction.getValue();
Base::Vector3d ourDir = DirProjection.getValue();
if (sourceDir != ourDir) {
Base::Console().Warning("Pattern %s may be incorrect due to source %d Direction change.\n",
getNameInDocument(),source->getNameInDocument());
}
adviseParent();
return App::DocumentObject::StdReturn;
}
void DrawCrosshatch::adviseParent(void) const
{
//if the hatch changes, the source has to change too. actually only the source's QGVI has to change.
DrawViewPart* parent = getSourceView();
if (parent) {
parent->touch();
parent->recomputeFeature();
}
}
DrawViewPart* DrawCrosshatch::getSourceView(void) const
{
App::DocumentObject* obj = Source.getValue();
DrawViewPart* result = dynamic_cast<DrawViewPart*>(obj);
return result;
}
//!get all the specification lines and decode them into HatchLine structures
std::vector<HatchLine> DrawCrosshatch::getDecodedSpecsFromFile()
{
std::vector<HatchLine> result;
std::string fileSpec = FilePattern.getValue();
std::string myPattern = NamePattern.getValue();
Base::FileInfo fi(fileSpec);
if (!fi.isReadable()) {
Base::Console().Error("DrawCrosshatch::getDecodedSpecsFromFile not able to open %s!\n",fileSpec.c_str());
return result;
}
result = HatchLine::getSpecsForPattern(fileSpec,myPattern);
return result;
}
std::vector<LineSet> DrawCrosshatch::getDrawableLines()
{
std::vector<LineSet> result;
DrawViewPart* source = getSourceView();
if (!source ||
!source->hasGeometry()) {
Base::Console().Message("TRACE - DC::getDrawableLines - no source geometry\n");
return result;
}
if (m_lineSets.empty()) {
Base::Console().Message("TRACE - DC::getDrawableLines - no LineSets!\n");
return result;
}
//get geometry for linked Face
const std::vector<std::string> &subElements = Source.getSubValues();
int idx = DrawUtil::getIndexFromName(subElements[0]);
//build wire(s) from geometry
std::vector<TopoDS_Wire> faceWires = source->getWireForFace(idx);
gp_Pln plane = source->getProjPlane();
BRepBuilderAPI_MakeFace mkFace(plane, faceWires.front(), true);
std::vector<TopoDS_Wire>::iterator itWire = ++faceWires.begin(); //starting with second wire
for (; itWire != faceWires.end(); itWire++) {
mkFace.Add(*itWire);
}
if (!mkFace.IsDone()) {
Base::Console().Message("TRACE - DC::getDrawableLines - face creation failed\n");
return result;
}
TopoDS_Face face = mkFace.Face();
Bnd_Box bBox;
BRepBndLib::Add(face, bBox);
bBox.SetGap(0.0);
// face & box are done!
for (auto& ls: m_lineSets) {
HatchLine hl = ls.getHatchLine();
std::vector<TopoDS_Edge> candidates = DrawCrosshatch::makeEdgeOverlay(hl, bBox);
//make Compound for this linespec
BRep_Builder builder;
TopoDS_Compound Comp;
builder.MakeCompound(Comp);
for (auto& c: candidates) {
builder.Add(Comp, c);
}
//Common Compound with Face
BRepAlgoAPI_Common mkCommon(face, Comp);
if ((!mkCommon.IsDone()) ||
(mkCommon.Shape().IsNull()) ) {
Base::Console().Message("TRACE - DC::getDrawableLines - Common creation failed\n");
return result;
}
TopoDS_Shape common = mkCommon.Shape();
//Save edges from Common
std::vector<TopoDS_Edge> resultEdges;
std::vector<TechDrawGeometry::BaseGeom*> resultGeoms;
TopTools_IndexedMapOfShape mapOfEdges;
TopExp::MapShapes(common, TopAbs_EDGE, mapOfEdges);
for ( int i = 1 ; i <= mapOfEdges.Extent() ; i++ ) {
const TopoDS_Edge& edge = TopoDS::Edge(mapOfEdges(i));
if (edge.IsNull()) {
Base::Console().Message("TRACE - DC::getDrawableLines - edge: %d is NULL\n",i);
continue;
}
TechDrawGeometry::BaseGeom* base = BaseGeom::baseFactory(edge);
if (base == nullptr) {
Base::Console().Message("TRACE - DC::getDrawableLines - baseFactory failed for edge: %d\n",i);
throw Base::Exception("GeometryObject::addGeomFromCompound - baseFactory failed");
}
resultGeoms.push_back(base);
resultEdges.push_back(edge);
}
ls.setEdges(resultEdges);
ls.setGeoms(resultGeoms);
result.push_back(ls);
}
return result;
}
std::vector<TopoDS_Edge> DrawCrosshatch::makeEdgeOverlay(HatchLine hl, Bnd_Box b)
{
std::vector<TopoDS_Edge> result;
double minX,maxX,minY,maxY,minZ,maxZ;
b.Get(minX,minY,minZ,maxX,maxY,maxZ);
Base::Vector3d start;
Base::Vector3d end;
Base::Vector3d origin = hl.getOrigin();
double interval = hl.getInterval() * ScalePattern.getValue();
double angle = hl.getAngle();
//only dealing with angles -180:180 for now
if (angle > 90.0) {
angle = -(180.0 - angle);
} else if (angle < -90.0) {
angle = (180 + angle);
}
angle = -angle; //not sure why this is required? inverted Y?
double slope = tan(angle * M_PI/180.0);
if (angle == 0.0) { //odd case 1: horizontal lines
double y = origin.y;
double x1 = minX;
double x2 = maxX;
start = Base::Vector3d(x1,y,0);
end = Base::Vector3d(x2,y,0);
int repeatUp = (int) ceil(((maxY - y)/interval) + 1);
int repeatDown = (int) ceil(((y - minY)/interval) + 1);
// make up repeats
int i;
for (i = 1; i < repeatUp; i++) {
Base::Vector3d newStart(minX,y + float(i)*interval,0);
Base::Vector3d newEnd(maxX,y + float(i)*interval,0);
TopoDS_Edge newLine = makeLine(newStart,newEnd);
result.push_back(newLine);
}
// make down repeats
for (i = 1; i < repeatDown; i++) {
Base::Vector3d newStart(minX, y - float(i)*interval,0);
Base::Vector3d newEnd(maxX, y - float(i)*interval,0);
TopoDS_Edge newLine = makeLine(newStart,newEnd);
result.push_back(newLine);
}
} else if (angle > 0) { //bottomleft - topright
double xRightAtom = origin.x + ((maxY - origin.y)/slope);
double xLeftAtom = origin.x + ((minY - origin.y)/slope);
start = Base::Vector3d(xLeftAtom,minY,0);
end = Base::Vector3d(xRightAtom,maxY,0);
int repeatRight = (int) ceil(((maxX - xLeftAtom)/interval) + 1);
int repeatLeft = (int) ceil(((xRightAtom - minX)/interval) + 1);
// make right repeats
int i;
for (i = 1; i < repeatRight; i++) {
Base::Vector3d newStart(start.x + float(i)*interval,minY,0);
Base::Vector3d newEnd(end.x + float(i)*interval,maxY,0);
TopoDS_Edge newLine = makeLine(newStart,newEnd);
result.push_back(newLine);
}
// make left repeats
for (i = 1; i < repeatLeft; i++) {
Base::Vector3d newStart(start.x - float(i)*interval,minY,0);
Base::Vector3d newEnd(end.x - float(i)*interval,maxY,0);
TopoDS_Edge newLine = makeLine(newStart,newEnd);
result.push_back(newLine);
}
} else { //topleft - bottomright
double x2 = origin.x + (maxY - origin.y)/slope;
double x1 = origin.x + (minY - origin.y)/slope;
start = Base::Vector3d(x2,maxY,0);
end = Base::Vector3d(x1,minY,0);
int repeatRight = (int) ceil(((maxX - start.x)/interval) + 1);
int repeatLeft = (int) ceil(((end.x - minX)/interval) + 1);
// make right repeats
int i;
for (i = 1; i < repeatRight; i++) {
Base::Vector3d newStart(start.x + float(i)*interval,maxY,0);
Base::Vector3d newEnd(end.x + float(i)*interval,minY,0);
TopoDS_Edge newLine = makeLine(newStart,newEnd);
result.push_back(newLine);
}
// make left repeats
for (i = 1; i < repeatLeft; i++) {
Base::Vector3d newStart(start.x - float(i)*interval,maxY,0);
Base::Vector3d newEnd(end.x - float(i)*interval,minY,0);
TopoDS_Edge newLine = makeLine(newStart,newEnd);
result.push_back(newLine);
}
}
//atom is centre line in a set of pattern lines.
TopoDS_Edge atom = makeLine(start,end);
result.push_back(atom);
return result;
}
TopoDS_Edge DrawCrosshatch::makeLine(Base::Vector3d s, Base::Vector3d e)
{
TopoDS_Edge result;
gp_Pnt start(s.x,s.y,0.0);
gp_Pnt end(e.x,e.y,0.0);
TopoDS_Vertex v1 = BRepBuilderAPI_MakeVertex(start);
TopoDS_Vertex v2 = BRepBuilderAPI_MakeVertex(end);
BRepBuilderAPI_MakeEdge makeEdge1(v1,v2);
result = makeEdge1.Edge();
return result;
}
PyObject *DrawCrosshatch::getPyObject(void)
{
if (PythonObject.is(Py::_None())) {
PythonObject = Py::Object(new DrawCrosshatchPy(this),true);
}
return Py::new_reference_to(PythonObject);
}
// Python Drawing feature ---------------------------------------------------------
namespace App {
/// @cond DOXERR
PROPERTY_SOURCE_TEMPLATE(TechDraw::DrawCrosshatchPython, TechDraw::DrawCrosshatch)
template<> const char* TechDraw::DrawCrosshatchPython::getViewProviderName(void) const {
return "TechDrawGui::ViewProviderCrosshatch";
}
/// @endcond
// explicit template instantiation
template class TechDrawExport FeaturePythonT<TechDraw::DrawCrosshatch>;
}

View File

@@ -0,0 +1,85 @@
/***************************************************************************
* Copyright (c) 2017 WandererFan <wandererfan@gmail.com> *
* *
* 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 *
* *
***************************************************************************/
#ifndef _TechDraw_DrawCrosshatch_h_
#define _TechDraw_DrawCrosshatch_h_
# include <App/DocumentObject.h>
# include <App/FeaturePython.h>
# include <App/PropertyLinks.h>
#include <App/PropertyFile.h>
#include "HatchLine.h"
#include "Geometry.h"
class TopoDS_Edge;
class Bnd_Box;
namespace TechDraw
{
class DrawViewPart;
class TechDrawExport DrawCrosshatch : public App::DocumentObject
{
PROPERTY_HEADER(TechDraw::DrawCrosshatch);
public:
DrawCrosshatch();
virtual ~DrawCrosshatch();
App::PropertyVector DirProjection; //Source is only valid for original projection?
App::PropertyLinkSub Source; //the dvp & face this crosshatch belongs to
App::PropertyFile FilePattern;
App::PropertyString NamePattern;
App::PropertyFloat ScalePattern;
// App::PropertyFloat WeightPattern;
// App::PropertyColor ColorPattern;
// App::PropertyStringList LineSpecs;
virtual short mustExecute() const;
virtual App::DocumentObjectExecReturn *execute(void);
virtual void onChanged(const App::Property* prop);
virtual const char* getViewProviderName(void) const {
return "TechDrawGui::ViewProviderCrosshatch";
}
virtual PyObject *getPyObject(void);
std::vector<LineSet> getDrawableLines();
DrawViewPart* getSourceView(void) const;
void adviseParent(void) const; //don't like this!
protected:
TopoDS_Edge makeLine(Base::Vector3d s, Base::Vector3d e);
std::vector<HatchLine> getDecodedSpecsFromFile();
std::vector<TopoDS_Edge> makeEdgeOverlay(HatchLine hl, Bnd_Box bBox);
std::vector<LineSet> m_lineSets;
private:
};
typedef App::FeaturePythonT<DrawCrosshatch> DrawCrosshatchPython;
} //namespace TechDraw
#endif

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="DocumentObjectPy"
Name="DrawCrosshatchPy"
Twin="DrawCrosshatch"
TwinPointer="DrawCrosshatch"
Include="Mod/TechDraw/App/DrawCrosshatch.h"
Namespace="TechDraw"
FatherInclude="App/DocumentObjectPy.h"
FatherNamespace="App">
<Documentation>
<Author Licence="LGPL" Name="WandererFan" EMail="wandererfan@gmail.com" />
<UserDocu>Feature for creating and manipulating Technical Drawing Crosshatch areas</UserDocu>
</Documentation>
<CustomAttributes />
</PythonExport>
</GenerateModel>

View File

@@ -0,0 +1,32 @@
#include "PreCompiled.h"
#include "DrawCrosshatch.h"
// inclusion of the generated files (generated out of DrawCrosshatchPy.xml)
#include <Mod/TechDraw/App/DrawCrosshatchPy.h>
#include <Mod/TechDraw/App/DrawCrosshatchPy.cpp>
using namespace TechDraw;
// returns a string which represents the object e.g. when printed in python
std::string DrawCrosshatchPy::representation(void) const
{
return std::string("<DrawCrosshatch object>");
}
PyObject *DrawCrosshatchPy::getCustomAttributes(const char* /*attr*/) const
{
return 0;
}
int DrawCrosshatchPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/)
{
return 0;
}

View File

@@ -69,7 +69,7 @@ DrawHatch::DrawHatch(void)
std::string defaultDir = App::Application::getResourceDir() + "Mod/Drawing/patterns/";
std::string defaultFileName = defaultDir + "simple.svg";
QString patternFileName = QString::fromStdString(hGrp->GetASCII("PatternFile",defaultFileName.c_str()));
QString patternFileName = QString::fromStdString(hGrp->GetASCII("FileHatch",defaultFileName.c_str()));
if (patternFileName.isEmpty()) {
patternFileName = QString::fromStdString(defaultFileName);
}

View File

@@ -292,6 +292,10 @@ void DrawPage::onDocumentRestored()
if (part != nullptr &&
!part->hasGeometry()) {
part->execute();
// std::vector<App::DocumentObject*> parent = part->getInList();
// for (auto& p: parent) {
// p->touch();
// }
}
}
//second, make sure all the Dimensions have been executed so Measurements have References

View File

@@ -1042,6 +1042,7 @@ void DrawProjGroup::onDocumentRestored()
}
std::string viewRot = Cube::dirToView(rotFront);
std::string config = viewDir + viewRot;
//find(config) or try/catch
try {
config = m_dirRotToConfig.at(config);
setConfig(config);

View File

@@ -33,6 +33,7 @@
#include <BRepAdaptor_Curve.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepLib.hxx>
#include <BRepLProp_CurveTool.hxx>
#include <BRepLProp_CLProps.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
@@ -83,6 +84,7 @@
#include "GeometryObject.h"
#include "DrawViewPart.h"
#include "DrawHatch.h"
#include "DrawCrosshatch.h"
#include "EdgeWalker.h"
@@ -147,19 +149,17 @@ App::DocumentObjectExecReturn *DrawViewPart::execute(void)
{
App::DocumentObject *link = Source.getValue();
if (!link) {
return new App::DocumentObjectExecReturn("FVP - No Source object linked");
return new App::DocumentObjectExecReturn("DVP - No Source object linked");
}
if (!link->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
return new App::DocumentObjectExecReturn("FVP - Linked object is not a Part object");
return new App::DocumentObjectExecReturn("DVP - Linked object is not a Part object");
}
TopoDS_Shape shape = static_cast<Part::Feature*>(link)->Shape.getShape().getShape();
if (shape.IsNull()) {
return new App::DocumentObjectExecReturn("FVP - Linked shape object is empty");
return new App::DocumentObjectExecReturn("DVP - Linked shape object is empty");
}
//Base::Console().Message("TRACE - DVP::execute() - %s - %s - dir: %s\n",getNameInDocument(), Label.getValue(),DrawUtil::formatVector(Direction.getValue()).c_str());
(void) DrawView::execute(); //make sure Scale is up to date
@@ -391,7 +391,6 @@ void DrawViewPart::extractFaces()
}
}
std::vector<TechDraw::DrawHatch*> DrawViewPart::getHatches() const
{
std::vector<TechDraw::DrawHatch*> result;
@@ -405,6 +404,19 @@ std::vector<TechDraw::DrawHatch*> DrawViewPart::getHatches() const
return result;
}
std::vector<TechDraw::DrawCrosshatch*> DrawViewPart::getCrosshatches() const
{
std::vector<TechDraw::DrawCrosshatch*> result;
std::vector<App::DocumentObject*> children = getInList();
for (std::vector<App::DocumentObject*>::iterator it = children.begin(); it != children.end(); ++it) {
if ((*it)->getTypeId().isDerivedFrom(DrawCrosshatch::getClassTypeId())) {
TechDraw::DrawCrosshatch* cross = dynamic_cast<TechDraw::DrawCrosshatch*>(*it);
result.push_back(cross);
}
}
return result;
}
const std::vector<TechDrawGeometry::Vertex *> & DrawViewPart::getVertexGeometry() const
{
return geometryObject->getVertexGeometry();
@@ -450,6 +462,8 @@ TechDrawGeometry::Vertex* DrawViewPart::getProjVertexByIndex(int idx) const
return geoms.at(idx);
}
//this is never used!!
//! returns existing geometry of 2D Face(idx)
//version 1 Face has 1 wire
std::vector<TechDrawGeometry::BaseGeom*> DrawViewPart::getProjFaceByIndex(int idx) const
@@ -467,6 +481,29 @@ std::vector<TechDrawGeometry::BaseGeom*> DrawViewPart::getProjFaceByIndex(int id
return result;
}
std::vector<TopoDS_Wire> DrawViewPart::getWireForFace(int idx) const
{
// Base::Console().Message("TRACE - DVP::getWireForFace(%d)\n",idx);
std::vector<TopoDS_Wire> result;
std::vector<TopoDS_Edge> edges;
const std::vector<TechDrawGeometry::Face *>& faces = getFaceGeometry();
TechDrawGeometry::Face * ourFace = faces.at(idx);
for (auto& w:ourFace->wires) {
edges.clear();
int i = 0;
for (auto& g:w->geoms) {
edges.push_back(g->occEdge);
// DrawUtil::dumpEdge("DVP Face edge",i,g->occEdge);
i++;
}
TopoDS_Wire occwire = EdgeWalker::makeCleanWire(edges);
// BRepLib::BuildCurves3d(occwire); //probably don't need this
result.push_back(occwire);
}
// Base::Console().Message("TRACE - DVP::getWireForFace(%d) returns %d wires\n",idx,result.size());
return result;
}
Base::BoundBox3d DrawViewPart::getBoundingBox() const
{
@@ -570,12 +607,24 @@ const std::vector<TechDrawGeometry::BaseGeom *> DrawViewPart::getVisibleFaceEdg
return geometryObject->getVisibleFaceEdges(SmoothVisible.getValue(),SeamVisible.getValue());
}
//is this really the projection plane??
gp_Pln DrawViewPart::getProjPlane() const
{
Base::Vector3d plnPnt(0.0,0.0,0.0);
Base::Vector3d plnNorm = Direction.getValue();
gp_Ax2 viewAxis = getViewAxis(plnPnt,plnNorm,false);
gp_Ax3 viewAxis3(viewAxis);
return gp_Pln(viewAxis3);
}
void DrawViewPart::getRunControl()
{
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/General");
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/RunControl");
m_sectionEdges = hGrp->GetBool("ShowSectionEdges", 1l);
m_handleFaces = hGrp->GetBool("HandleFaces", 1l);
//Base::Console().Message("TRACE - DVP::getRunControl - handleFaces: %d\n",m_handleFaces);
}
bool DrawViewPart::handleFaces(void)

View File

@@ -40,6 +40,7 @@
#include "DrawProjectSplit.h"
class gp_Pnt;
class gp_Pln;
namespace TechDrawGeometry
{
@@ -51,6 +52,7 @@ class Face;
namespace TechDraw {
class DrawHatch;
class DrawCrosshatch;
}
namespace TechDraw
@@ -91,6 +93,7 @@ public:
std::vector<TechDraw::DrawHatch*> getHatches(void) const;
std::vector<TechDraw::DrawCrosshatch*> getCrosshatches(void) const;
//TODO: are there use-cases for Python access to TechDrawGeometry???
@@ -136,6 +139,10 @@ public:
//return PyObject as DrawViewPartPy
virtual PyObject *getPyObject(void);
bool isDeleting(void) { return nowDeleting; }
gp_Pln getProjPlane(void) const;
std::vector<TopoDS_Wire> getWireForFace(int idx) const;
protected:
TechDrawGeometry::GeometryObject *geometryObject;

View File

@@ -545,7 +545,7 @@ void DrawViewSection::getParameters()
std::string defaultDir = App::Application::getResourceDir() + "Mod/Drawing/patterns/";
std::string defaultFileName = defaultDir + "simple.svg";
QString patternFileName = QString::fromStdString(hGrp->GetASCII("PatternFile",defaultFileName.c_str()));
QString patternFileName = QString::fromStdString(hGrp->GetASCII("FileHatch",defaultFileName.c_str()));
if (patternFileName.isEmpty()) {
patternFileName = QString::fromStdString(defaultFileName);
}

View File

@@ -265,7 +265,7 @@ std::vector<TopoDS_Wire> EdgeWalker::getResultNoDups()
return fw;
}
//* static *//
//! make a clean wire with sorted, oriented, connected, etc edges
TopoDS_Wire EdgeWalker::makeCleanWire(std::vector<TopoDS_Edge> edges, double tol)
{

View File

@@ -175,7 +175,7 @@ public:
int findUniqueVert(TopoDS_Vertex vx, std::vector<TopoDS_Vertex> &uniqueVert);
std::vector<TopoDS_Wire> sortStrip(std::vector<TopoDS_Wire> fw, bool includeBiggest);
std::vector<TopoDS_Wire> sortWiresBySize(std::vector<TopoDS_Wire>& w, bool reverse = false);
TopoDS_Wire makeCleanWire(std::vector<TopoDS_Edge> edges, double tol = 0.10);
static TopoDS_Wire makeCleanWire(std::vector<TopoDS_Edge> edges, double tol = 0.10);
std::vector<int> getEmbeddingRowIx(int v);
std::vector<edge_t> getEmbeddingRow(int v);

View File

@@ -161,7 +161,8 @@ void GeometryObject::projectShape(const TopoDS_Shape& input,
HLRAlgo_Projector projector( viewAxis );
brep_hlr->Projector(projector);
brep_hlr->Update();
brep_hlr->Hide();
brep_hlr->Hide(); //XXXX: what happens if we don't call Hide()?? and only look at VCompound?
// WF: you get back all the edges in the shape, but very fast!!
}
catch (...) {
Standard_Failure::Raise("GeometryObject::projectShape - error occurred while projecting shape");

View File

@@ -0,0 +1,237 @@
/***************************************************************************
* Copyright (c) 2017 Wandererfan <wandererfan@gmail.com> *
* *
* 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"
#ifndef _PreComp_
#include <sstream>
#include <iomanip>
#include <QFile>
#include <QFileInfo>
#include <stdexcept>
#endif
#include <Base/Console.h>
#include "DrawUtil.h"
#include "HatchLine.h"
using namespace TechDraw;
HatchLine::HatchLine()
{
init();
}
HatchLine::HatchLine(std::string& lineSpec)
{
init();
load(lineSpec);
}
HatchLine::~HatchLine()
{
}
void HatchLine::init(void)
{
m_angle = 0.0;
m_origin = Base::Vector3d(0.0,0.0,0.0);
m_interval = 1.0;
m_offset = 0.0;
}
void HatchLine::load(std::string& lineSpec)
{
std::vector<double> values = split(lineSpec);
if (values.size() < 5) {
Base::Console().Message( "HatchLine::load(%s) invalid entry in pattern\n",lineSpec.c_str() );
return;
}
m_angle = values[0];
m_origin = Base::Vector3d(values[1],values[2],0.0);
m_offset = values[3];
m_interval = values[4];
if (values.size() > 5) {
m_dashParms.insert(std::end(m_dashParms), std::begin(values) + 5, std::end(values));
}
}
std::vector<double> HatchLine::split(std::string line)
{
std::vector<double> result;
std::stringstream lineStream(line);
std::string cell;
while(std::getline(lineStream,cell, ','))
{
try {
result.push_back(std::stod(cell));
}
catch (const std::invalid_argument& ia) {
Base::Console().Warning("Invalid number in cell: %s (%s) \n",cell.c_str(),ia.what());
result.push_back(0.0);
}
}
return result;
}
void HatchLine::dump(char* title)
{
Base::Console().Message( "DUMP: %s\n",title);
Base::Console().Message( "Angle: %.3f\n", m_angle);
Base::Console().Message( "Origin: %s\n",DrawUtil::formatVector(m_origin).c_str());
Base::Console().Message( "Offset: %.3f\n",m_offset);
Base::Console().Message( "Interval: %.3f\n",m_interval);
std::stringstream ss;
for (auto& d: m_dashParms) {
ss << d << ", ";
}
ss << "end";
Base::Console().Message( "DashSpec: %s\n",ss.str().c_str());
}
//static class methods
std::vector<HatchLine> HatchLine::getSpecsForPattern(std::string& parmFile, std::string& parmName)
{
std::vector<HatchLine> result;
std::vector<std::string> lineSpecs;
std::ifstream inFile;
inFile.open (parmFile, std::ifstream::in);
if(!inFile.is_open()) {
Base::Console().Message( "Cannot open input file.\n");
return result;
}
//get all the definition lines for this pattern
bool status = findPatternStart(inFile, parmName);
if (status) {
lineSpecs = loadPatternDef(inFile);
} else {
Base::Console().Message( "Could not find pattern: %s\n",parmName.c_str() );
return result;
}
//decode definition lines into HatchLine objects
for (auto& l: lineSpecs) {
HatchLine hl(l);
result.push_back(hl);
}
return result;
}
bool HatchLine::findPatternStart(std::ifstream& inFile, std::string& parmName)
{
bool result = false;
while ( inFile.good() ){
std::string line;
std::getline(inFile,line);
std::string nameTag = line.substr(0,1);
std::string patternName;
unsigned long int commaPos;
if ((nameTag == ";") ||
(nameTag == " ") ||
(line.empty()) ) { //is cr/lf empty?
continue;
} else if (nameTag == "*") {
commaPos = line.find(",",1);
if (commaPos != std::string::npos) {
patternName = line.substr(1,commaPos-1);
} else {
patternName = line.substr(1);
}
if (patternName == parmName) {
//this is our pattern
result = true;
break;
}
}
} //endwhile
return result;
}
//get the definition lines for this pattern
std::vector<std::string> HatchLine::loadPatternDef(std::ifstream& inFile)
{
std::vector<std::string> result;
while ( inFile.good() ){
std::string line;
std::getline(inFile,line);
std::string nameTag = line.substr(0,1);
if ((nameTag == ";") ||
(nameTag == " ") ||
(line.empty()) ) { //is cr/lf empty?
continue;
} else if (nameTag == "*") {
break;
} else { //dataline
result.push_back(line);
}
}
return result;
}
std::vector<std::string> HatchLine::getPatternList(std::string& parmFile)
{
std::vector<std::string> result;
std::ifstream inFile;
inFile.open (parmFile, std::ifstream::in);
if(!inFile.is_open()) {
Base::Console().Message( "Cannot open input file.\n");
return result;
}
while ( inFile.good() ){
std::string line;
std::getline(inFile,line);
std::string nameTag = line.substr(0,1); //dupl code here
unsigned long int commaPos;
if (nameTag == "*") { //found a pattern
commaPos = line.find(",",1);
std::string patternName;
if (commaPos != std::string::npos) {
patternName = line.substr(1,commaPos-1);
} else {
patternName = line.substr(1);
}
result.push_back(patternName);
}
}
return result;
}
//********************************************************
void DashSpec::dump(char* title)
{
std::stringstream ss;
ss << title << ": " ;
for (auto& p: m_parms) {
ss << p << ", ";
}
Base::Console().Message("DUMP - DashSpec - %s\n",ss.str().c_str());
}

View File

@@ -0,0 +1,117 @@
/***************************************************************************
* Copyright (c) 2017 Wandererfan <wandererfan@gmail.com> *
* *
* 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 *
* *
***************************************************************************/
#ifndef _TechDraw_HATCHLINE_H_
#define _TechDraw_HATCHLINE_H_
#include <iostream>
#include <sstream>
#include <fstream>
#include <vector>
#include <string>
#include <Base/Vector3D.h>
#include "Geometry.h"
namespace TechDraw
{
class DrawViewPart;
class DrawUtil;
// HatchLine is the result of parsing a line from PAT file into accessible parameters
class HatchLine
{
public:
HatchLine();
HatchLine(std::string& lineSpec);
~HatchLine();
void load(std::string& lineSpec);
double getAngle(void) {return m_angle;}
Base::Vector3d getOrigin(void) {return m_origin;}
double getInterval(void) {return m_interval;}
double getOffset(void) {return m_offset;}
std::vector<double> getDashParms(void) {return m_dashParms;};
static std::vector<HatchLine> getSpecsForPattern(std::string& parmFile, std::string& parmName);
static bool findPatternStart(std::ifstream& inFile, std::string& parmName);
static std::vector<std::string> loadPatternDef(std::ifstream& inFile);
static std::vector<std::string> getPatternList(std::string& parmFile);
void dump(char* title);
private:
void init(void);
std::vector<double> split(std::string line);
double m_angle;
Base::Vector3d m_origin;
double m_interval;
double m_offset;
std::vector<double> m_dashParms; //why isn't this a DashSpec object?
};
// a LineSet is all the generated edges for a HatchLine
class LineSet
{
public:
LineSet() {}
~LineSet() {}
void setHatchLine(HatchLine s) { m_hatchLine = s; }
void setEdges(std::vector<TopoDS_Edge> e) {m_edges = e;}
void setGeoms(std::vector<TechDrawGeometry::BaseGeom*> g) {m_geoms = g;}
HatchLine getHatchLine(void) { return m_hatchLine; }
std::vector<double> getDashSpec(void) { return m_hatchLine.getDashParms();}
std::vector<TopoDS_Edge> getEdges(void) { return m_edges; }
std::vector<TechDrawGeometry::BaseGeom*> getGeoms(void) { return m_geoms; }
private:
std::vector<TopoDS_Edge> m_edges;
std::vector<TechDrawGeometry::BaseGeom*> m_geoms;
HatchLine m_hatchLine;
};
class DashSpec
{
public:
DashSpec() {}
DashSpec(std::vector<double> p) { m_parms = p; }
~DashSpec() {}
double get(int i) {return m_parms.at(i); }
std::vector<double> get(void) {return m_parms;}
bool empty(void) {return m_parms.empty();}
int size(void) {return m_parms.size();}
void dump(char* title);
private:
std::vector<double> m_parms;
};
} //end namespace
#endif

View File

@@ -48,6 +48,7 @@
#include "ViewProviderSymbol.h"
#include "ViewProviderViewClip.h"
#include "ViewProviderHatch.h"
#include "ViewProviderCrosshatch.h"
#include "ViewProviderSpreadsheet.h"
#include "ViewProviderImage.h"
@@ -102,6 +103,7 @@ void TechDrawGuiExport initTechDrawGui()
TechDrawGui::ViewProviderDraft::init();
TechDrawGui::ViewProviderArch::init();
TechDrawGui::ViewProviderHatch::init();
TechDrawGui::ViewProviderCrosshatch::init();
TechDrawGui::ViewProviderSpreadsheet::init();
TechDrawGui::ViewProviderImage::init();

View File

@@ -199,6 +199,8 @@ SET(TechDrawGuiViewProvider_SRCS
ViewProviderViewClip.h
ViewProviderHatch.cpp
ViewProviderHatch.h
ViewProviderCrosshatch.cpp
ViewProviderCrosshatch.h
ViewProviderImage.cpp
ViewProviderImage.h
)

View File

@@ -49,6 +49,7 @@
#include <Mod/TechDraw/App/DrawView.h>
#include <Mod/TechDraw/App/DrawViewPart.h>
#include <Mod/TechDraw/App/DrawHatch.h>
#include <Mod/TechDraw/App/DrawCrosshatch.h>
#include <Mod/TechDraw/App/DrawPage.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include <Mod/TechDraw/Gui/QGVPage.h>
@@ -126,6 +127,69 @@ bool CmdTechDrawNewHatch::isActive(void)
return (havePage && haveView);
}
//===========================================================================
// TechDraw_NewCrosshatch
//===========================================================================
DEF_STD_CMD_A(CmdTechDrawNewCrosshatch);
CmdTechDrawNewCrosshatch::CmdTechDrawNewCrosshatch()
: Command("TechDraw_NewCrosshatch")
{
sAppModule = "TechDraw";
sGroup = QT_TR_NOOP("TechDraw");
sMenuText = QT_TR_NOOP("Insert a crosshatched area into a view");
sToolTipText = QT_TR_NOOP("Insert a crosshatched area into a view");
sWhatsThis = "TechDraw_NewCrosshatch";
sStatusTip = sToolTipText;
sPixmap = "actions/techdraw-crosshatch";
}
void CmdTechDrawNewCrosshatch::activated(int iMsg)
{
Q_UNUSED(iMsg);
if (!_checkSelectionHatch(this)) { //same requirements as hatch - page, DrawViewXXX, face
return;
}
std::vector<Gui::SelectionObject> selection = getSelection().getSelectionEx();
auto objFeat( dynamic_cast<TechDraw::DrawViewPart *>(selection[0].getObject()) );
if( objFeat == nullptr ) {
return;
}
const std::vector<std::string> &subNames = selection[0].getSubNames();
TechDraw::DrawPage* page = objFeat->findParentPage();
std::string PageName = page->getNameInDocument();
std::string FeatName = getUniqueObjectName("Crosshatch");
std::stringstream featLabel;
featLabel << FeatName << "FX" << TechDraw::DrawUtil::getIndexFromName(subNames.at(0));
Base::Console().Message("TRACE - cmd::newCrossHatch - %s - %s\n",featLabel.str().c_str(), FeatName.c_str());
openCommand("Create Crosshatch");
doCommand(Doc,"App.activeDocument().addObject('TechDraw::DrawCrosshatch','%s')",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Label = '%s'",FeatName.c_str(),featLabel.str().c_str());
auto crosshatch( static_cast<TechDraw::DrawCrosshatch *>(getDocument()->getObject(FeatName.c_str())) );
crosshatch->Source.setValue(objFeat, subNames);
commitCommand();
Base::Console().Message("TRACE - cmd::newCrossHatch - complete\n");
//Horrible hack to force Tree update ??still required??
double x = objFeat->X.getValue();
objFeat->X.setValue(x);
getDocument()->recompute();
}
bool CmdTechDrawNewCrosshatch::isActive(void)
{
bool havePage = DrawGuiUtil::needPage(this);
bool haveView = DrawGuiUtil::needView(this);
return (havePage && haveView);
}
//===========================================================================
// TechDraw_Image
//===========================================================================
@@ -230,6 +294,7 @@ void CreateTechDrawCommandsDecorate(void)
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.addCommand(new CmdTechDrawNewHatch());
rcCmdMgr.addCommand(new CmdTechDrawNewCrosshatch());
rcCmdMgr.addCommand(new CmdTechDrawImage());
rcCmdMgr.addCommand(new CmdTechDrawToggleFrame());
}

View File

@@ -82,7 +82,7 @@
<item row="2" column="1">
<widget class="Gui::PrefFileChooser" name="pfc_HatchFile">
<property name="prefEntry" stdset="0">
<cstring>PatternFile</cstring>
<cstring>FileHatch</cstring>
</property>
<property name="prefPath" stdset="0">
<cstring>/Mod/TechDraw/Files</cstring>

View File

@@ -379,12 +379,12 @@ void MDIViewPage::updateDrawing(bool forceUpdate)
// WF: the QGVP views list may still not be 100% reliable
// TODO: build list of QGIV's from scene everytime?
//logging counters
int qgvpIn = 0;
int qgvpValid = 0;
int qgvpClean = 0;
int dpIn = 0;
// int qgvpIn = 0;
// int qgvpValid = 0;
// int qgvpClean = 0;
// int dpIn = 0;
const std::vector<QGIView *> &graphicsList = m_view->getViews();
qgvpIn = graphicsList.size();
// qgvpIn = graphicsList.size();
const std::vector<App::DocumentObject*> &pageChildren = m_vpPage->getDrawPage()->Views.getValues();
// Count total # DocumentObjects in Page
@@ -397,7 +397,7 @@ void MDIViewPage::updateDrawing(bool forceUpdate)
}
docObjCount += 1;
}
dpIn = docObjCount;
// dpIn = docObjCount;
//TODO: should prune QGVP.views first always, then check if view in Page missing QGIVP
@@ -426,7 +426,7 @@ void MDIViewPage::updateDrawing(bool forceUpdate)
}
}
}
qgvpValid = newGraphicsList.size();
// qgvpValid = newGraphicsList.size();
//newGraphicsList now only contains valid QGIV's
//now prune the ones without docObjs
std::vector<QGIView *> cleanItems;
@@ -452,10 +452,10 @@ void MDIViewPage::updateDrawing(bool forceUpdate)
cleanItems.push_back(v);
}
}
qgvpClean = cleanItems.size();
// qgvpClean = cleanItems.size();
m_view->setViews(cleanItems);
Base::Console().Message("Log - MDIVP::updateDrawing pruning: docObjs: %d views in: %d valid views: %d views out: %d\n",
dpIn,qgvpIn,qgvpValid, qgvpClean);
// Base::Console().Message("Log - MDIVP::updateDrawing pruning: docObjs: %d views in: %d valid views: %d views out: %d\n",
// dpIn,qgvpIn,qgvpValid, qgvpClean);
}
// Update all the QGIVxxxx

View File

@@ -48,12 +48,15 @@
#include <Base/Console.h>
#include <Base/Parameter.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include "Rez.h"
#include "QGCustomSvg.h"
#include "QGCustomRect.h"
#include "QGIFace.h"
using namespace TechDrawGui;
using namespace TechDraw;
QGIFace::QGIFace(int index) :
projIndex(index),
@@ -61,8 +64,8 @@ QGIFace::QGIFace(int index) :
m_styleDef(Qt::SolidPattern),
m_styleSelect(Qt::SolidPattern)
{
m_isHatched = false;
m_mode = 0;
setFillMode(NoFill);
isHatched(false);
setFlag(QGraphicsItem::ItemClipsChildrenToShape,true);
//setStyle(Qt::NoPen); //don't draw face lines, just fill for debugging
@@ -71,8 +74,11 @@ QGIFace::QGIFace(int index) :
m_styleNormal = m_styleDef;
m_fillStyle = m_styleDef;
m_colNormalFill = m_colDefFill;
setCrosshatchColor(QColor(Qt::black));
setCrosshatchWeight(0.5); //0 = cosmetic
setPrettyNormal();
m_texture = QPixmap();
m_texture = nullptr; //empty texture
m_svg = new QGCustomSvg();
@@ -80,7 +86,7 @@ QGIFace::QGIFace(int index) :
m_rect->setParentItem(this);
m_svgCol = SVGCOLDEFAULT;
m_svgScale = 1.0;
m_fillScale = 1.0;
}
QGIFace::~QGIFace()
@@ -90,22 +96,47 @@ QGIFace::~QGIFace()
void QGIFace::draw()
{
setPath(m_outline); //Face boundary
if (isHatched()) {
QFileInfo hfi(QString::fromUtf8(m_fileSpec.data(),m_fileSpec.size()));
if (hfi.isReadable()) {
QString ext = hfi.suffix();
if (ext.toUpper() == QString::fromUtf8("SVG")) {
m_mode = 1;
loadSvgHatch(m_fileSpec);
buildSvgHatch();
toggleSvg(true);
} else if ((ext.toUpper() == QString::fromUtf8("JPG")) ||
(ext.toUpper() == QString::fromUtf8("PNG")) ||
(ext.toUpper() == QString::fromUtf8("JPEG")) ||
(ext.toUpper() == QString::fromUtf8("BMP")) ) {
m_mode = 2;
toggleSvg(false);
m_texture = textureFromBitmap(m_fileSpec);
if (m_mode == CrosshatchFill) { //crosshatch
if (!m_crossHatchPaths.empty()) { //surrogate for LineSets.empty
m_brush.setTexture(nullptr);
m_fillStyle = m_styleDef;
m_styleNormal = m_fillStyle;
int pathNo = 0;
for (auto& pp: m_crossHatchPaths) {
QGraphicsPathItem* fillItem = m_fillItems.at(pathNo);
fillItem->setPath(pp);
QPen crossPen = setCrossPen(pathNo);
fillItem->setPen(crossPen);
pathNo++;
}
}
} else if ((m_mode == FromFile) ||
(m_mode == SvgFill) ||
(m_mode == BitmapFill)) {
QFileInfo hfi(QString::fromUtf8(m_fileSpec.data(),m_fileSpec.size()));
if (hfi.isReadable()) {
QString ext = hfi.suffix();
if (ext.toUpper() == QString::fromUtf8("SVG")) {
setFillMode(SvgFill);
m_brush.setTexture(nullptr);
m_fillStyle = m_styleDef;
m_styleNormal = m_fillStyle;
loadSvgHatch(m_fileSpec);
buildSvgHatch();
toggleSvg(true);
} else if ((ext.toUpper() == QString::fromUtf8("JPG")) ||
(ext.toUpper() == QString::fromUtf8("PNG")) ||
(ext.toUpper() == QString::fromUtf8("JPEG")) ||
(ext.toUpper() == QString::fromUtf8("BMP")) ) {
setFillMode(BitmapFill);
toggleSvg(false);
m_fillStyle = Qt::TexturePattern;
m_texture = textureFromBitmap(m_fileSpec);
m_brush.setTexture(m_texture);
}
}
}
}
@@ -114,23 +145,27 @@ void QGIFace::draw()
void QGIFace::setPrettyNormal() {
if (isHatched() &&
(m_mode == 2) ) { //hatch with bitmap fill
(m_mode == BitmapFill) ) { //hatch with bitmap fill
m_fillStyle = Qt::TexturePattern;
m_brush.setTexture(m_texture);
} else {
m_fillStyle = m_styleNormal;
m_brush.setTexture(nullptr);
m_brush.setStyle(m_fillStyle);
m_fillColor = m_colNormalFill;
}
m_fillColor = m_colNormalFill;
QGIPrimPath::setPrettyNormal();
}
void QGIFace::setPrettyPre() {
m_brush.setTexture(nullptr);
m_fillStyle = m_styleSelect;
m_fillColor = getPreColor();
QGIPrimPath::setPrettyPre();
}
void QGIFace::setPrettySel() {
m_brush.setTexture(nullptr);
m_fillStyle = m_styleSelect;
m_fillColor = getSelectColor();
QGIPrimPath::setPrettySel();
@@ -164,21 +199,110 @@ void QGIFace::loadSvgHatch(std::string fileSpec)
}
}
void QGIFace::setPath(const QPainterPath & path)
void QGIFace::setFillMode(QGIFace::fillMode m)
{
QGraphicsPathItem::setPath(path);
if ((m_mode == 1) && !m_svgXML.isEmpty()) { // svg hatch mode and have svg hatch info loded
buildSvgHatch();
m_mode = m;
if ((m_mode == NoFill) ||
(m_mode == PlainFill)) {
isHatched(false);
} else {
isHatched(true);
}
}
void QGIFace::setOutline(const QPainterPath & path)
{
m_outline = path;
}
void QGIFace::clearLineSets(void)
{
m_crossHatchPaths.clear();
m_dashSpecs.clear();
clearFillItems();
}
//each line set needs a painterpath, a dashspec and a QGPItem to show them
void QGIFace::addLineSet(QPainterPath pp, std::vector<double> dp)
{
m_crossHatchPaths.push_back(pp);
m_dashSpecs.push_back(DashSpec(dp));
addFillItem();
}
QGraphicsPathItem* QGIFace::addFillItem()
{
QGraphicsPathItem* fillItem = new QGraphicsPathItem();
fillItem->setParentItem(this);
m_fillItems.push_back(fillItem);
return fillItem;
}
void QGIFace::clearFillItems(void)
{
for (auto& f: m_fillItems) {
f->setParentItem(nullptr);
this->scene()->removeItem(f);
delete f;
}
}
void QGIFace::setCrosshatchColor(const QColor& c)
{
m_crossColor = c;
}
//convert from PAT style "-1,0,-1,+1" to Qt style "mark,space,mark,space"
QVector<qreal> QGIFace::decodeDashSpec(DashSpec patDash)
{
//Rez::guiX(something)?
double dotLength = 3.0; //guess work!
double unitLength = 6.0;
//double penWidth = m_crossWeight;
std::vector<double> result;
for (auto& d: patDash.get()) {
double strokeLength;
if (DrawUtil::fpCompare(d,0.0)) { //pat dot
strokeLength = dotLength;
result.push_back(strokeLength);
} else if (Rez::guiX(d) < 0) { //pat space
strokeLength = fabs(Rez::guiX(d)) * unitLength;
result.push_back(strokeLength);
} else { //pat dash
strokeLength = Rez::guiX(d) * unitLength;
result.push_back(strokeLength);
}
}
return QVector<qreal>::fromStdVector( result );
}
QPen QGIFace::setCrossPen(int i)
{
//m_dashSpecs[i].dump("spec test");
DashSpec ourSpec = m_dashSpecs.at(i);
//ourSpec.dump("our spec");
QPen result;
// result.setWidthF(m_crossWeight);
result.setWidthF(Rez::guiX(0.09));
result.setColor(m_crossColor);
if (ourSpec.empty()) {
result.setStyle(Qt::SolidLine);
} else {
result.setStyle(Qt::CustomDashLine);
result.setDashPattern(decodeDashSpec(ourSpec));
}
return result;
}
void QGIFace::buildSvgHatch()
{
double wTile = SVGSIZEW * m_svgScale;
double hTile = SVGSIZEH * m_svgScale;
double w = boundingRect().width();
double h = boundingRect().height();
QRectF r = boundingRect();
double wTile = SVGSIZEW * m_fillScale;
double hTile = SVGSIZEH * m_fillScale;
double w = m_outline.boundingRect().width();
double h = m_outline.boundingRect().height();
QRectF r = m_outline.boundingRect();
QPointF fCenter = r.center();
double nw = ceil(w / wTile);
double nh = ceil(h / hTile);
@@ -194,7 +318,7 @@ void QGIFace::buildSvgHatch()
for (int iw = 0; iw < int(nw); iw++) {
for (int ih = 0; ih < int(nh); ih++) {
QGCustomSvg* tile = new QGCustomSvg();
tile->setScale(m_svgScale);
tile->setScale(m_fillScale);
if (tile->load(&colorXML)) {
tile->setParentItem(m_rect);
tile->setPos(iw*wTile,-h + ih*hTile);
@@ -220,7 +344,7 @@ QPixmap QGIFace::textureFromSvg(std::string fileSpec)
pixMap.fill(Qt::white); //try Qt::transparent?
QPainter painter(&pixMap);
renderer.render(&painter); //svg texture -> bitmap
result = pixMap.scaled(m_svgScale,m_svgScale);
result = pixMap.scaled(m_fillScale,m_fillScale);
} //else return empty pixmap
return result;
}
@@ -234,7 +358,7 @@ void QGIFace::setHatchColor(std::string c)
void QGIFace::setHatchScale(double s)
{
m_svgScale = s;
m_fillScale = s;
}
//QtSvg does not handle clipping, so we must be able to turn the hatching on/off
@@ -255,7 +379,7 @@ QPixmap QGIFace::textureFromBitmap(std::string fileSpec)
QFileInfo ffi(qs);
if (ffi.isReadable()) {
QImage img = QImage(qs);
img = img.scaled(Rez::guiX(m_svgScale),Rez::guiX(m_svgScale));
img = img.scaled(Rez::guiX(m_fillScale),Rez::guiX(m_fillScale));
pix = QPixmap::fromImage(img);
}
return pix;
@@ -296,3 +420,4 @@ void QGIFace::paint ( QPainter * painter, const QStyleOptionGraphicsItem * optio
setBrush(m_brush);
QGIPrimPath::paint (painter, &myOption, widget);
}

View File

@@ -30,8 +30,12 @@
#include <QBrush>
#include <QPixmap>
#include <Mod/TechDraw/App/HatchLine.h>
#include "QGIPrimPath.h"
using namespace TechDraw;
namespace TechDrawGui
{
class QGCustomSvg;
@@ -55,48 +59,78 @@ public:
virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 );
public:
enum fillMode {
NoFill,
FromFile,
SvgFill,
BitmapFill,
CrosshatchFill,
PlainFill
};
int getProjIndex() const { return projIndex; }
void draw();
void setPrettyNormal();
void setPrettyPre();
void setPrettySel();
void setPath(const QPainterPath & path);
void setDrawEdges(bool b);
virtual void setOutline(const QPainterPath& path);
//shared fill parms
void isHatched(bool s) {m_isHatched = s; }
bool isHatched(void) {return m_isHatched;}
void setFillMode(fillMode m);
//plain color fill parms
void setFill(QColor c, Qt::BrushStyle s);
void setFill(QBrush b);
void resetFill();
//svg fill parms & methods
void setHatchFile(std::string fileSpec);
void setHatchColor(std::string c);
void setHatchScale(double s);
void loadSvgHatch(std::string fileSpec);
void buildSvgHatch(void);
void toggleSvg(bool b);
void clearSvg(void);
//PAT fill parms & methods
// void setCrosshatch(const QPainterPath& p);
void setCrosshatchColor(const QColor& c);
void setCrosshatchWeight(double w) { m_crossWeight = w; }
//void setLineSets(std::vector<LineSet> ls);
void clearLineSets(void);
void addLineSet(QPainterPath pp, std::vector<double> dp);
QGraphicsPathItem* addFillItem();
void clearFillItems(void);
//bitmap texture fill parms method
QPixmap textureFromBitmap(std::string fileSpec);
QPixmap textureFromSvg(std::string fillSpec);
void isHatched(bool s) {m_isHatched = s; }
bool isHatched(void) {return m_isHatched;}
protected:
// bool load(QByteArray *svgBytes);
protected:
int projIndex; //index of face in Projection. -1 for SectionFace.
QGCustomRect *m_rect;
QGCustomSvg *m_svg;
QByteArray m_svgXML;
std::string m_svgCol;
double m_svgScale;
std::string m_fileSpec;
std::string m_fileSpec; //for svg & bitmaps
double m_fillScale;
bool m_isHatched;
int m_mode;
QGIFace::fillMode m_mode;
QPen setCrossPen(int i);
QVector<qreal> decodeDashSpec(DashSpec d);
// QGraphicsPathItem* m_fillItem;
std::vector<QGraphicsPathItem*> m_fillItems;
std::vector<QPainterPath> m_crossHatchPaths; // 0/1 dashspec per crosshatchpath
std::vector<DashSpec> m_dashSpecs;
private:
QBrush m_brush;
@@ -108,7 +142,15 @@ private:
Qt::BrushStyle m_styleDef; //default Normal fill style
Qt::BrushStyle m_styleNormal; //current Normal fill style
Qt::BrushStyle m_styleSelect; //Select/preSelect fill style
QPixmap m_texture; //
QPainterPath m_outline; //
QPainterPath m_crosshatch; //crosshatch fill lines
QColor m_crossColor; //color for crosshatch lines
double m_crossWeight; //lineweight for crosshatch lines
};
}

View File

@@ -44,6 +44,10 @@
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/ViewProvider.h>
#include "Rez.h"
#include "QGCustomBorder.h"
@@ -451,6 +455,15 @@ QGIView* QGIView::getQGIVByName(std::string name)
return 0;
}
/* static */
Gui::ViewProvider* QGIView::getViewProvider(App::DocumentObject* obj)
{
Gui::Document* guiDoc = Gui::Application::Instance->getDocument(obj->getDocument());
Gui::ViewProvider* result = guiDoc->getViewProvider(obj);
return result;
}
QColor QGIView::getNormalColor()
{
Base::Reference<ParameterGrp> hGrp = getParmGroupCol();

View File

@@ -27,8 +27,10 @@
#include <QPen>
#include <QFont>
#include <App/DocumentObject.h>
#include <App/PropertyLinks.h>
#include <Base/Parameter.h>
#include <Gui/ViewProvider.h>
#include <Mod/TechDraw/App/DrawView.h>
@@ -87,6 +89,8 @@ public:
virtual QColor getNormalColor(void);
virtual QColor getPreColor(void);
virtual QColor getSelectColor(void);
static Gui::ViewProvider* getViewProvider(App::DocumentObject* obj);
protected:
QGIView* getQGIVByName(std::string name);

View File

@@ -46,11 +46,13 @@
#include <App/Material.h>
#include <Base/Console.h>
#include <Base/Vector3D.h>
#include <Gui/ViewProvider.h>
#include <Mod/TechDraw/App/DrawUtil.h>
#include <Mod/TechDraw/App/DrawViewPart.h>
#include <Mod/TechDraw/App/DrawViewSection.h>
#include <Mod/TechDraw/App/DrawHatch.h>
#include <Mod/TechDraw/App/DrawCrosshatch.h>
#include <Mod/TechDraw/App/DrawViewDetail.h>
#include "Rez.h"
@@ -66,6 +68,7 @@
#include "QGCustomRect.h"
#include "QGIMatting.h"
#include "QGIViewPart.h"
#include "ViewProviderCrosshatch.h"
using namespace TechDrawGui;
using namespace TechDrawGeometry;
@@ -375,21 +378,49 @@ void QGIViewPart::drawViewPart()
if (viewPart->handleFaces()) {
// Draw Faces
std::vector<TechDraw::DrawHatch*> hatchObjs = viewPart->getHatches();
std::vector<TechDraw::DrawCrosshatch*> crossObjs = viewPart->getCrosshatches();
const std::vector<TechDrawGeometry::Face *> &faceGeoms = viewPart->getFaceGeometry();
std::vector<TechDrawGeometry::Face *>::const_iterator fit = faceGeoms.begin();
for(int i = 0 ; fit != faceGeoms.end(); fit++, i++) {
QGIFace* newFace = drawFace(*fit,i);
newFace->isHatched(false);
newFace->setFillMode(QGIFace::PlainFill);
TechDraw::DrawHatch* fHatch = faceIsHatched(i,hatchObjs);
if (fHatch) {
TechDraw::DrawCrosshatch* fCross = faceIsCrosshatched(i,crossObjs);
if (fCross) {
std::vector<LineSet> lineSets = fCross->getDrawableLines();
if (!lineSets.empty()) {
newFace->clearLineSets();
for (auto& ls: lineSets) {
QPainterPath bigPath;
for (auto& g: ls.getGeoms()) {
QPainterPath smallPath = drawPainterPath(g);
bigPath.addPath(smallPath);
}
newFace->addLineSet(bigPath,ls.getDashSpec());
}
newFace->isHatched(true);
newFace->setFillMode(QGIFace::CrosshatchFill);
newFace->setHatchScale(fCross->ScalePattern.getValue());
Gui::ViewProvider* gvp = QGIView::getViewProvider(fCross);
ViewProviderCrosshatch* crossVp = dynamic_cast<ViewProviderCrosshatch*>(gvp);
if (crossVp != nullptr) {
App::Color hColor = crossVp->ColorPattern.getValue();
newFace->setCrosshatchColor(hColor.asValue<QColor>());
// newFace->setLineWeight(crossVp->WeightPattern.getValue());
}
}
} else if (fHatch) {
if (!fHatch->HatchPattern.isEmpty()) {
newFace->setHatchFile(fHatch->HatchPattern.getValue());
App::Color hColor = fHatch->HatchColor.getValue();
newFace->setHatchColor(hColor.asCSSString());
newFace->setHatchScale(fHatch->HatchScale.getValue());
newFace->isHatched(true);
newFace->setFillMode(QGIFace::FromFile);
}
}
newFace->setDrawEdges(false);
}
newFace->setDrawEdges(true);
newFace->setZValue(ZVALUE::FACE);
newFace->draw();
newFace->setPrettyNormal();
@@ -502,7 +533,7 @@ QGIFace* QGIViewPart::drawFace(TechDrawGeometry::Face* f, int idx)
QGIFace* gFace = new QGIFace(idx);
addToGroup(gFace);
gFace->setPos(0.0,0.0);
gFace->setPath(facePath);
gFace->setOutline(facePath);
//debug a path
//std::stringstream faceId;
//faceId << "facePath " << idx;
@@ -853,6 +884,21 @@ TechDraw::DrawHatch* QGIViewPart::faceIsHatched(int i,std::vector<TechDraw::Draw
return result;
}
TechDraw::DrawCrosshatch* QGIViewPart::faceIsCrosshatched(int i,std::vector<TechDraw::DrawCrosshatch*> crossObjs) const
{
TechDraw::DrawCrosshatch* result = nullptr;
for (auto& h:crossObjs) {
const std::vector<std::string> &sourceNames = h->Source.getSubValues();
int fdx = TechDraw::DrawUtil::getIndexFromName(sourceNames.at(0));
if (fdx == i) {
result = h;
break;
}
}
return result;
}
void QGIViewPart::dumpPath(const char* text,QPainterPath path)
{
QPainterPath::Element elem;

View File

@@ -34,6 +34,7 @@ namespace TechDraw {
class DrawViewPart;
class DrawViewSection;
class DrawHatch;
class DrawCrosshatch;
}
namespace TechDrawGui
@@ -89,6 +90,7 @@ protected:
virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value) override;
TechDraw::DrawHatch* faceIsHatched(int i,std::vector<TechDraw::DrawHatch*> hatchObjs) const;
TechDraw::DrawCrosshatch* faceIsCrosshatched(int i,std::vector<TechDraw::DrawCrosshatch*> crossObjs) const;
void dumpPath(const char* text,QPainterPath path);
void removePrimitives(void);
void removeDecorations(void);

View File

@@ -49,6 +49,7 @@
<file>icons/actions/techdraw-saveSVG.svg</file>
<file>icons/actions/techdraw-viewsection.svg</file>
<file>icons/actions/techdraw-hatch.svg</file>
<file>icons/actions/techdraw-crosshatch.svg</file>
<file>icons/actions/techdraw-toggleframe.svg</file>
<file>icons/actions/techdraw-projgroup.svg</file>
<file>icons/actions/techdraw-spreadsheet.svg</file>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,126 @@
/***************************************************************************
* Copyright (c) 2004 Jürgen Riegel <juergen.riegel@web.de> *
* Copyright (c) 2017 Wandererfan <wandererfan@gmail.com> *
* *
* 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"
#ifndef _PreComp_
#endif
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObject.h>
#include <Base/Console.h>
#include <Base/Parameter.h>
#include <Base/Exception.h>
#include <Base/Sequencer.h>
//#include <Gui/SoFCSelection.h>
#include <Gui/Selection.h>
#include <Mod/TechDraw/App/DrawCrosshatch.h>
#include <Mod/TechDraw/App/DrawView.h>
#include "ViewProviderCrosshatch.h"
using namespace TechDrawGui;
PROPERTY_SOURCE(TechDrawGui::ViewProviderCrosshatch, Gui::ViewProviderDocumentObject)
//**************************************************************************
// Construction/Destruction
ViewProviderCrosshatch::ViewProviderCrosshatch()
{
static const char *vgroup = "Format";
sPixmap = "actions/techdraw-crosshatch";
App::Color fcColor;
fcColor.setPackedValue(0x00000000);
ADD_PROPERTY_TYPE(ColorPattern,(fcColor),vgroup,App::Prop_None,"The color of the pattern");
ADD_PROPERTY_TYPE(WeightPattern,(0.0),vgroup,App::Prop_None,"Crosshatch pattern line thickness");
}
ViewProviderCrosshatch::~ViewProviderCrosshatch()
{
}
void ViewProviderCrosshatch::attach(App::DocumentObject *pcFeat)
{
// call parent attach method
ViewProviderDocumentObject::attach(pcFeat);
}
void ViewProviderCrosshatch::setDisplayMode(const char* ModeName)
{
ViewProviderDocumentObject::setDisplayMode(ModeName);
}
std::vector<std::string> ViewProviderCrosshatch::getDisplayModes(void) const
{
// get the modes of the father
std::vector<std::string> StrList = ViewProviderDocumentObject::getDisplayModes();
return StrList;
}
//for VP properties
void ViewProviderCrosshatch::onChanged(const App::Property* prop)
{
// Base::Console().Message("TRACE - VPC::onChanged(%s)\n",prop->getName());
Gui::ViewProviderDocumentObject::onChanged(prop);
}
//for feature properties
void ViewProviderCrosshatch::updateData(const App::Property* prop)
{
// Base::Console().Message("TRACE - VPC::updateData(%s)\n",prop->getName());
if (prop == &WeightPattern ||
prop == &ColorPattern ||
prop == &(getViewObject()->ScalePattern)) {
//Base::Console().Message("TRACE - VPC::updateData - should update parent now\n");
//how does QGIVP find this VP to get properties?
// Gui::ViewProvider* view = Application::Instance->getDocument(it->pDoc)->getViewProvider(it->pObject);
// TechDraw::DrawPage* fp = dynamic_cast<TechDraw::DrawPage*>(getDocument()->getObject(PageName.c_str()));
// Gui::ViewProvider* vp = Gui::Application::Instance->getDocument(getDocument())->getViewProvider(fp);
// TechDrawGui::ViewProviderPage* dvp = dynamic_cast<TechDrawGui::ViewProviderPage*>(vp);
// if (dvp) {
// dvp->show();
// redraw QGIVP
//QGIView* qgiv = getQView(); this will be different have to find source's QView
// if (qgiv) {
// qgiv->updateView(true);
// }
}
Gui::ViewProviderDocumentObject::updateData(prop);
}
TechDraw::DrawCrosshatch* ViewProviderCrosshatch::getViewObject() const
{
return dynamic_cast<TechDraw::DrawCrosshatch*>(pcObject);
}

View File

@@ -0,0 +1,69 @@
/***************************************************************************
* Copyright (c) 2004 Jürgen Riegel <juergen.riegel@web.de> *
* Copyright (c) 2017 Wandererfan <wandererfan@gmail.com> *
* *
* 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 *
* *
***************************************************************************/
#ifndef DRAWINGGUI_VIEWPROVIDERCROSSHATCH_H
#define DRAWINGGUI_VIEWPROVIDERCROSSHATCH_H
#include <App/DocumentObject.h>
#include <App/FeaturePython.h>
#include <App/PropertyStandard.h>
#include <Gui/ViewProviderFeature.h>
namespace TechDraw{
class DrawCrosshatch;
}
namespace TechDrawGui {
class TechDrawGuiExport ViewProviderCrosshatch : public Gui::ViewProviderDocumentObject
{
PROPERTY_HEADER(TechDrawGui::ViewProviderCrosshatch);
public:
/// constructor
ViewProviderCrosshatch();
/// destructor
virtual ~ViewProviderCrosshatch();
App::PropertyFloat WeightPattern;
App::PropertyColor ColorPattern;
virtual void attach(App::DocumentObject *);
virtual void updateData(const App::Property*);
virtual void onChanged(const App::Property *prop);
virtual bool useNewSelectionModel(void) const {return false;}
virtual void setDisplayMode(const char* ModeName);
virtual std::vector<std::string> getDisplayModes(void) const;
TechDraw::DrawCrosshatch* getViewObject() const;
};
} // namespace TechDrawGui
#endif // DRAWINGGUI_VIEWPROVIDERHATCH_H

View File

@@ -39,6 +39,7 @@
#include <Mod/TechDraw/App/DrawViewDimension.h>
#include <Mod/TechDraw/App/DrawViewMulti.h>
#include <Mod/TechDraw/App/DrawHatch.h>
#include <Mod/TechDraw/App/DrawCrosshatch.h>
#include<Mod/TechDraw/App/DrawPage.h>
#include "ViewProviderViewPart.h"
@@ -117,6 +118,7 @@ std::vector<App::DocumentObject*> ViewProviderViewPart::claimChildren(void) cons
// valid children of a ViewPart are:
// - Dimensions
// - Hatches
// - Crosshatches
std::vector<App::DocumentObject*> temp;
const std::vector<App::DocumentObject *> &views = getViewPart()->getInList();
try {
@@ -132,6 +134,8 @@ std::vector<App::DocumentObject*> ViewProviderViewPart::claimChildren(void) cons
}
} else if ((*it)->getTypeId().isDerivedFrom(TechDraw::DrawHatch::getClassTypeId())) {
temp.push_back((*it));
} else if ((*it)->getTypeId().isDerivedFrom(TechDraw::DrawCrosshatch::getClassTypeId())) {
temp.push_back((*it));
}
}
return temp;

View File

@@ -133,6 +133,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
Gui::ToolBarItem *decor = new Gui::ToolBarItem(root);
decor->setCommand("TechDraw Decoration");
*decor << "TechDraw_NewHatch";
*decor << "TechDraw_NewCrosshatch";
*decor << "TechDraw_Image";
*decor << "TechDraw_ToggleFrame";
return root;
@@ -182,6 +183,7 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const
Gui::ToolBarItem *decor = new Gui::ToolBarItem(root);
decor->setCommand("TechDraw Decoration");
*decor << "TechDraw_NewHatch";
*decor << "TechDraw_NewCrosshatch";
*decor << "TechDraw_Image";
*decor << "TechDraw_ToggleFrame";

View File

@@ -0,0 +1,21 @@
; standard PAT patterns
*Diamond, 45 diagonals L & R, Solid, 1.0 mm separation
45,0,0,0,1.0
-45,0,0,0,1.0
*Diamond2, 45 diagonals L & R, Solid, 2.0 mm separation
45,0,0,0,2.0
-45,0,0,0,2.0
*Diamond4, 45 diagonals L & R, Solid, 4.0 mm separation
45,0,0,0,4.0
-45,0,0,0,4.0
*Diagonal4, 45 diagonal R, Solid, 4.0 mm separation
45,0,0,0,4.0
*Square, square grid, Solid, 5.0 mm separation
90,1,1,0,5.0
0,0,0,1,5.0
*Horizontal5, horizontal lines, Solid 5.0 separation
0,0,0,0,5.0
*Vertical5, vertical lines, Solid, 5.0 separation
90,0,0,0,5.0