Initial working version of geometric crosshatch/PAT files
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
445
src/Mod/TechDraw/App/DrawCrosshatch.cpp
Normal file
445
src/Mod/TechDraw/App/DrawCrosshatch.cpp
Normal 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>;
|
||||
}
|
||||
85
src/Mod/TechDraw/App/DrawCrosshatch.h
Normal file
85
src/Mod/TechDraw/App/DrawCrosshatch.h
Normal 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
|
||||
18
src/Mod/TechDraw/App/DrawCrosshatchPy.xml
Normal file
18
src/Mod/TechDraw/App/DrawCrosshatchPy.xml
Normal 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>
|
||||
32
src/Mod/TechDraw/App/DrawCrosshatchPyImp.cpp
Normal file
32
src/Mod/TechDraw/App/DrawCrosshatchPyImp.cpp
Normal 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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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");
|
||||
|
||||
237
src/Mod/TechDraw/App/HatchLine.cpp
Normal file
237
src/Mod/TechDraw/App/HatchLine.cpp
Normal 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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
117
src/Mod/TechDraw/App/HatchLine.h
Normal file
117
src/Mod/TechDraw/App/HatchLine.h
Normal 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
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -199,6 +199,8 @@ SET(TechDrawGuiViewProvider_SRCS
|
||||
ViewProviderViewClip.h
|
||||
ViewProviderHatch.cpp
|
||||
ViewProviderHatch.h
|
||||
ViewProviderCrosshatch.cpp
|
||||
ViewProviderCrosshatch.h
|
||||
ViewProviderImage.cpp
|
||||
ViewProviderImage.h
|
||||
)
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 |
126
src/Mod/TechDraw/Gui/ViewProviderCrosshatch.cpp
Normal file
126
src/Mod/TechDraw/Gui/ViewProviderCrosshatch.cpp
Normal 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);
|
||||
}
|
||||
69
src/Mod/TechDraw/Gui/ViewProviderCrosshatch.h
Normal file
69
src/Mod/TechDraw/Gui/ViewProviderCrosshatch.h
Normal 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
|
||||
@@ -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;
|
||||
|
||||
@@ -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";
|
||||
|
||||
|
||||
21
src/Mod/TechDraw/PAT/FCStd.pat
Normal file
21
src/Mod/TechDraw/PAT/FCStd.pat
Normal 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
|
||||
|
||||
Reference in New Issue
Block a user