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
|
||||
Reference in New Issue
Block a user