clean up GeomHatch feature, gui & dialog
Refactor code, allow dialog to edit feature, update graphics on change prep for dash line start positioning.
This commit is contained in:
@@ -68,6 +68,7 @@
|
||||
#include "HatchLine.h"
|
||||
#include "DrawUtil.h"
|
||||
#include "Geometry.h"
|
||||
#include "DrawPage.h"
|
||||
#include "DrawViewPart.h"
|
||||
#include "DrawViewSection.h"
|
||||
#include "DrawGeomHatch.h"
|
||||
@@ -94,6 +95,9 @@ DrawGeomHatch::DrawGeomHatch(void)
|
||||
ADD_PROPERTY_TYPE(NamePattern,(""),vgroup,App::Prop_None,"The name of the pattern");
|
||||
ADD_PROPERTY_TYPE(ScalePattern,(1.0),vgroup,App::Prop_None,"GeomHatch pattern size adjustment");
|
||||
ScalePattern.setConstraints(&scaleRange);
|
||||
|
||||
m_saveFile = "";
|
||||
m_saveName = "";
|
||||
|
||||
getParameters();
|
||||
|
||||
@@ -105,28 +109,18 @@ DrawGeomHatch::~DrawGeomHatch()
|
||||
|
||||
void DrawGeomHatch::onChanged(const App::Property* prop)
|
||||
{
|
||||
if (prop == &Source ) {
|
||||
if (prop == &Source ) {
|
||||
if (!isRestoring()) {
|
||||
DrawGeomHatch::execute();
|
||||
DrawGeomHatch::execute();
|
||||
}
|
||||
}
|
||||
if (isRestoring()) {
|
||||
if ((prop == &FilePattern) || //make sure right pattern gets loaded at start up
|
||||
(prop == &NamePattern)) {
|
||||
DrawGeomHatch::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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
App::DocumentObject::onChanged(prop);
|
||||
}
|
||||
|
||||
@@ -148,7 +142,23 @@ short DrawGeomHatch::mustExecute() const
|
||||
|
||||
App::DocumentObjectExecReturn *DrawGeomHatch::execute(void)
|
||||
{
|
||||
|
||||
//save names & check if different
|
||||
if ((!FilePattern.isEmpty()) &&
|
||||
(!NamePattern.isEmpty())) {
|
||||
if ((m_saveFile != FilePattern.getValue()) ||
|
||||
(m_saveName != NamePattern.getValue())) {
|
||||
m_saveFile = FilePattern.getValue();
|
||||
m_saveName = NamePattern.getValue();
|
||||
std::vector<PATLineSpec> specs = getDecodedSpecsFromFile();
|
||||
m_lineSets.clear();
|
||||
for (auto& hl: specs) {
|
||||
//hl.dump("hl from file");
|
||||
LineSet ls;
|
||||
ls.setPATLineSpec(hl);
|
||||
m_lineSets.push_back(ls);
|
||||
}
|
||||
}
|
||||
}
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
|
||||
@@ -159,7 +169,7 @@ DrawViewPart* DrawGeomHatch::getSourceView(void) const
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<HatchLine> DrawGeomHatch::getDecodedSpecsFromFile()
|
||||
std::vector<PATLineSpec> DrawGeomHatch::getDecodedSpecsFromFile()
|
||||
{
|
||||
std::string fileSpec = FilePattern.getValue();
|
||||
std::string myPattern = NamePattern.getValue();
|
||||
@@ -167,49 +177,265 @@ std::vector<HatchLine> DrawGeomHatch::getDecodedSpecsFromFile()
|
||||
}
|
||||
|
||||
|
||||
//!get all the specification lines and decode them into HatchLine structures
|
||||
//!get all the specification lines and decode them into PATLineSpec structures
|
||||
/*static*/
|
||||
std::vector<HatchLine> DrawGeomHatch::getDecodedSpecsFromFile(std::string fileSpec, std::string myPattern)
|
||||
std::vector<PATLineSpec> DrawGeomHatch::getDecodedSpecsFromFile(std::string fileSpec, std::string myPattern)
|
||||
{
|
||||
std::vector<HatchLine> result;
|
||||
std::vector<PATLineSpec> result;
|
||||
Base::FileInfo fi(fileSpec);
|
||||
if (!fi.isReadable()) {
|
||||
Base::Console().Error("DrawGeomHatch::getDecodedSpecsFromFile not able to open %s!\n",fileSpec.c_str());
|
||||
return result;
|
||||
}
|
||||
result = HatchLine::getSpecsForPattern(fileSpec,myPattern);
|
||||
result = PATLineSpec::getSpecsForPattern(fileSpec,myPattern);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<LineSet> DrawGeomHatch::getDrawableLines(int i) //get the drawable lines for face i
|
||||
std::vector<LineSet> DrawGeomHatch::getTrimmedLines(int i) //get the trimmed hatch lines for face i
|
||||
{
|
||||
std::vector<LineSet> result;
|
||||
DrawViewPart* source = getSourceView();
|
||||
if (!source ||
|
||||
!source->hasGeometry()) {
|
||||
Base::Console().Message("TRACE - DC::getDrawableLines - no source geometry\n");
|
||||
Base::Console().Message("TRACE - DGH::getTrimmedLines - no source geometry\n");
|
||||
return result;
|
||||
}
|
||||
return getDrawableLines(source, m_lineSets,i, ScalePattern.getValue());
|
||||
return getTrimmedLines(source, m_lineSets,i, ScalePattern.getValue());
|
||||
}
|
||||
|
||||
/* static */
|
||||
std::vector<LineSet> DrawGeomHatch::getDrawableLines(DrawViewPart* source, std::vector<LineSet> lineSets, int iface, double scale )
|
||||
//! get hatch lines trimmed to face outline
|
||||
std::vector<LineSet> DrawGeomHatch::getTrimmedLines(DrawViewPart* source, std::vector<LineSet> lineSets, int iface, double scale )
|
||||
{
|
||||
std::vector<LineSet> result;
|
||||
|
||||
//is source is a section?
|
||||
if (lineSets.empty()) {
|
||||
Base::Console().Log("INFO - DGH::getTrimmedLines - no LineSets!\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
TopoDS_Face face = extractFace(source,iface);
|
||||
|
||||
|
||||
Bnd_Box bBox;
|
||||
BRepBndLib::Add(face, bBox);
|
||||
bBox.SetGap(0.0);
|
||||
|
||||
for (auto& ls: lineSets) {
|
||||
PATLineSpec hl = ls.getPATLineSpec();
|
||||
std::vector<TopoDS_Edge> candidates = DrawGeomHatch::makeEdgeOverlay(hl, bBox, scale); //completely cover face bbox with lines
|
||||
|
||||
//make Compound for this linespec
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound Comp;
|
||||
builder.MakeCompound(Comp);
|
||||
for (auto& c: candidates) {
|
||||
builder.Add(Comp, c);
|
||||
}
|
||||
|
||||
//Common(Compound,Face)
|
||||
BRepAlgoAPI_Common mkCommon(face, Comp);
|
||||
if ((!mkCommon.IsDone()) ||
|
||||
(mkCommon.Shape().IsNull()) ) {
|
||||
Base::Console().Log("INFO - DGH::getTrimmedLines - Common creation failed\n");
|
||||
return result;
|
||||
}
|
||||
TopoDS_Shape common = mkCommon.Shape();
|
||||
Bnd_Box overlayBox;
|
||||
overlayBox.SetGap(0.0);
|
||||
BRepBndLib::Add(common, overlayBox);
|
||||
ls.setBBox(overlayBox);
|
||||
|
||||
|
||||
//get resulting edges
|
||||
std::vector<TopoDS_Edge> resultEdges;
|
||||
TopTools_IndexedMapOfShape mapOfEdges;
|
||||
TopExp::MapShapes(common, TopAbs_EDGE, mapOfEdges);
|
||||
for ( int i = 1 ; i <= mapOfEdges.Extent() ; i++ ) { //remember, TopExp makes no promises about the order it finds edges
|
||||
const TopoDS_Edge& edge = TopoDS::Edge(mapOfEdges(i));
|
||||
if (edge.IsNull()) {
|
||||
Base::Console().Log("INFO - DGH::getTrimmedLines - edge: %d is NULL\n",i);
|
||||
continue;
|
||||
}
|
||||
resultEdges.push_back(edge);
|
||||
}
|
||||
|
||||
std::vector<TechDrawGeometry::BaseGeom*> resultGeoms;
|
||||
int i = 0;
|
||||
for (auto& e: resultEdges) {
|
||||
TechDrawGeometry::BaseGeom* base = BaseGeom::baseFactory(e);
|
||||
if (base == nullptr) {
|
||||
Base::Console().Log("FAIL - DGH::getTrimmedLines - baseFactory failed for edge: %d\n",i);
|
||||
throw Base::Exception("DGH::getTrimmedLines - baseFactory failed");
|
||||
}
|
||||
resultGeoms.push_back(base);
|
||||
i++;
|
||||
}
|
||||
ls.setEdges(resultEdges);
|
||||
ls.setGeoms(resultGeoms);
|
||||
result.push_back(ls);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/* static */
|
||||
std::vector<TopoDS_Edge> DrawGeomHatch::makeEdgeOverlay(PATLineSpec hl, Bnd_Box b, double scale)
|
||||
{
|
||||
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() * scale;
|
||||
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);
|
||||
}
|
||||
double slope = hl.getSlope();
|
||||
|
||||
if (angle == 0.0) { //odd case 1: horizontal lines
|
||||
double y = origin.y;
|
||||
int repeatUp = (int) ceil(((maxY - y)/interval) + 1);
|
||||
int repeatDown = (int) ceil(((y - minY)/interval) + 1);
|
||||
int repeatTotal = repeatUp + repeatDown;
|
||||
|
||||
// make repeats
|
||||
for (int i = 0; i < repeatTotal; i++) {
|
||||
Base::Vector3d newStart(minX,minY + float(i)*interval,0);
|
||||
Base::Vector3d newEnd(maxX,minY + float(i)*interval,0);
|
||||
TopoDS_Edge newLine = makeLine(newStart,newEnd);
|
||||
result.push_back(newLine);
|
||||
}
|
||||
} else if ((angle == 90.0) ||
|
||||
(angle == -90.0)) { //odd case 2: vertical lines
|
||||
double x = origin.x;
|
||||
int repeatRight = (int) ceil(((maxX - x)/interval) + 1);
|
||||
int repeatLeft = (int) ceil(((x - minX)/interval) + 1);
|
||||
int repeatTotal = repeatRight + repeatLeft;
|
||||
|
||||
// make repeats
|
||||
for (int i = 0; i < repeatTotal; i++) {
|
||||
Base::Vector3d newStart(minX + float(i)*interval,minY,0);
|
||||
Base::Vector3d newEnd(minX + float(i)*interval,maxY,0);
|
||||
TopoDS_Edge newLine = makeLine(newStart,newEnd);
|
||||
result.push_back(newLine);
|
||||
}
|
||||
//TODO: check if this makes 2-3 extra lines. might be some "left" lines on "right" side of vv
|
||||
} else if (angle > 0) { //oblique (bottom left -> top right)
|
||||
//ex: 60,0,0,0,4.0,25,-25
|
||||
// Base::Console().Message("TRACE - DGH-makeEdgeOverlay - making angle > 0\n");
|
||||
double xLeftAtom = origin.x + (minY - origin.y)/slope; //the "atom" is the fill line that passes through the
|
||||
//pattern-origin (not necc. R2 origin)
|
||||
double xRightAtom = origin.x + (maxY - origin.y)/slope;
|
||||
int repeatRight = (int) ceil(((maxX - xLeftAtom)/interval) + 1);
|
||||
int repeatLeft = (int) ceil(((xRightAtom - minX)/interval) + 1);
|
||||
|
||||
double leftStartX = xLeftAtom - (repeatLeft * interval);
|
||||
double leftEndX = xRightAtom - (repeatLeft * interval);
|
||||
int repeatTotal = repeatRight + repeatLeft;
|
||||
|
||||
//make repeats
|
||||
for (int i = 0; i < repeatTotal; i++) {
|
||||
Base::Vector3d newStart(leftStartX + (float(i) * interval),minY,0);
|
||||
Base::Vector3d newEnd (leftEndX + (float(i) * interval),maxY,0);
|
||||
TopoDS_Edge newLine = makeLine(newStart,newEnd);
|
||||
result.push_back(newLine);
|
||||
}
|
||||
} else { //oblique (bottom right -> top left)
|
||||
// ex: -60,0,0,0,4.0,25.0,-12.5,12.5,-6
|
||||
// Base::Console().Message("TRACE - DGH-makeEdgeOverlay - making angle < 0\n");
|
||||
double xRightAtom = origin.x + ((minY - origin.y)/slope); //x-coord of left end of Atom line
|
||||
double xLeftAtom = origin.x + ((maxY - origin.y)/slope); //x-coord of right end of Atom line
|
||||
int repeatRight = (int) ceil(((maxX - xLeftAtom)/interval) + 1); //number of lines to Right of Atom
|
||||
int repeatLeft = (int) ceil(((xRightAtom - minX)/interval) + 1);//number of lines to Left of Atom
|
||||
double leftEndX = xLeftAtom - (repeatLeft * interval);
|
||||
double leftStartX = xRightAtom - (repeatLeft * interval);
|
||||
int repeatTotal = repeatRight + repeatLeft;
|
||||
|
||||
// make repeats
|
||||
for (int i = 0; i < repeatTotal; i++) {
|
||||
Base::Vector3d newStart(leftStartX + float(i)*interval,minY,0);
|
||||
Base::Vector3d newEnd(leftEndX + float(i)*interval,maxY,0);
|
||||
TopoDS_Edge newLine = makeLine(newStart,newEnd);
|
||||
result.push_back(newLine);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
TopoDS_Edge DrawGeomHatch::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;
|
||||
}
|
||||
|
||||
//! get all the untrimed hatchlines for a face
|
||||
//! these will be clipped to shape on the gui side
|
||||
std::vector<LineSet> DrawGeomHatch::getFaceOverlay(int fdx)
|
||||
{
|
||||
// Base::Console().Message("TRACE - DGH::getFaceOverlay(%d)\n",fdx);
|
||||
std::vector<LineSet> result;
|
||||
DrawViewPart* source = getSourceView();
|
||||
if (!source ||
|
||||
!source->hasGeometry()) {
|
||||
Base::Console().Message("TRACE - DGH::getFaceOverlay - no source geometry\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
TopoDS_Face face = extractFace(source,fdx);
|
||||
|
||||
Bnd_Box bBox;
|
||||
BRepBndLib::Add(face, bBox);
|
||||
bBox.SetGap(0.0);
|
||||
|
||||
for (auto& ls: m_lineSets) {
|
||||
PATLineSpec hl = ls.getPATLineSpec();
|
||||
std::vector<TopoDS_Edge> candidates = DrawGeomHatch::makeEdgeOverlay(hl, bBox, ScalePattern.getValue());
|
||||
std::vector<TechDrawGeometry::BaseGeom*> resultGeoms;
|
||||
int i = 0;
|
||||
for (auto& e: candidates) {
|
||||
TechDrawGeometry::BaseGeom* base = BaseGeom::baseFactory(e);
|
||||
if (base == nullptr) {
|
||||
Base::Console().Log("FAIL - DGH::getFaceOverlay - baseFactory failed for edge: %d\n",i);
|
||||
throw Base::Exception("DGH::getFaceOverlay - baseFactory failed");
|
||||
}
|
||||
resultGeoms.push_back(base);
|
||||
i++;
|
||||
}
|
||||
ls.setEdges(candidates);
|
||||
ls.setGeoms(resultGeoms);
|
||||
result.push_back(ls);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* static */
|
||||
//! get TopoDS_Face(iface) from DVP
|
||||
TopoDS_Face DrawGeomHatch::extractFace(DrawViewPart* source, int iface )
|
||||
{
|
||||
TopoDS_Face result;
|
||||
|
||||
//is source a section?
|
||||
DrawViewSection* section = dynamic_cast<DrawViewSection*>(source);
|
||||
bool usingSection = false;
|
||||
if (section != nullptr) {
|
||||
usingSection = true;
|
||||
}
|
||||
|
||||
if (lineSets.empty()) {
|
||||
Base::Console().Log("INFO - DC::getDrawableLines - no LineSets!\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<TopoDS_Wire> faceWires;
|
||||
if (usingSection) {
|
||||
@@ -229,176 +455,14 @@ std::vector<LineSet> DrawGeomHatch::getDrawableLines(DrawViewPart* source, std::
|
||||
mkFace.Add(*itWire);
|
||||
}
|
||||
if (!mkFace.IsDone()) {
|
||||
Base::Console().Log("INFO - DC::getDrawableLines - face creation failed\n");
|
||||
Base::Console().Log("INFO - DGH::extractFace - face creation failed\n");
|
||||
return result;
|
||||
}
|
||||
TopoDS_Face face = mkFace.Face();
|
||||
|
||||
Bnd_Box bBox;
|
||||
BRepBndLib::Add(face, bBox);
|
||||
bBox.SetGap(0.0);
|
||||
|
||||
for (auto& ls: lineSets) {
|
||||
HatchLine hl = ls.getHatchLine();
|
||||
std::vector<TopoDS_Edge> candidates = DrawGeomHatch::makeEdgeOverlay(hl, bBox, scale);
|
||||
|
||||
//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().Log("INFO - 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().Log("INFO - DC::getDrawableLines - edge: %d is NULL\n",i);
|
||||
continue;
|
||||
}
|
||||
TechDrawGeometry::BaseGeom* base = BaseGeom::baseFactory(edge);
|
||||
if (base == nullptr) {
|
||||
Base::Console().Log("FAIL - 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);
|
||||
}
|
||||
result = mkFace.Face();
|
||||
return result;
|
||||
}
|
||||
/* static */
|
||||
std::vector<TopoDS_Edge> DrawGeomHatch::makeEdgeOverlay(HatchLine hl, Bnd_Box b, double scale)
|
||||
{
|
||||
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 interval = hl.getInterval() * scale;
|
||||
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 DrawGeomHatch::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;
|
||||
}
|
||||
|
||||
void DrawGeomHatch::getParameters(void)
|
||||
{
|
||||
//this is probably "/build/data/Mod/TechDraw/PAT"
|
||||
Base::Reference<ParameterGrp> hGrp = App::GetApplication().GetUserParameter()
|
||||
.GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/PAT");
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <App/PropertyFile.h>
|
||||
|
||||
class TopoDS_Edge;
|
||||
class TopoDS_Face;
|
||||
class Bnd_Box;
|
||||
|
||||
namespace TechDrawGeometry
|
||||
@@ -39,7 +40,7 @@ class BaseGeom;
|
||||
namespace TechDraw
|
||||
{
|
||||
class DrawViewPart;
|
||||
class HatchLine;
|
||||
class PATLineSpec;
|
||||
class LineSet;
|
||||
class DashSet;
|
||||
|
||||
@@ -66,17 +67,21 @@ public:
|
||||
|
||||
DrawViewPart* getSourceView(void) const;
|
||||
|
||||
std::vector<LineSet> getDrawableLines(int i = 0);
|
||||
static std::vector<LineSet> getDrawableLines(DrawViewPart* dvp, std::vector<LineSet> lineSets, int iface, double scale);
|
||||
std::vector<LineSet> getFaceOverlay(int i = 0);
|
||||
std::vector<LineSet> getTrimmedLines(int i = 0);
|
||||
static std::vector<LineSet> getTrimmedLines(DrawViewPart* dvp, std::vector<LineSet> lineSets, int iface, double scale);
|
||||
|
||||
static std::vector<TopoDS_Edge> makeEdgeOverlay(HatchLine hl, Bnd_Box bBox, double scale);
|
||||
static std::vector<TopoDS_Edge> makeEdgeOverlay(PATLineSpec hl, Bnd_Box bBox, double scale);
|
||||
static TopoDS_Edge makeLine(Base::Vector3d s, Base::Vector3d e);
|
||||
static std::vector<HatchLine> getDecodedSpecsFromFile(std::string fileSpec, std::string myPattern);
|
||||
static std::vector<PATLineSpec> getDecodedSpecsFromFile(std::string fileSpec, std::string myPattern);
|
||||
static TopoDS_Face extractFace(DrawViewPart* source, int iface );
|
||||
|
||||
protected:
|
||||
void getParameters(void);
|
||||
std::vector<HatchLine> getDecodedSpecsFromFile();
|
||||
std::vector<PATLineSpec> getDecodedSpecsFromFile();
|
||||
std::vector<LineSet> m_lineSets;
|
||||
std::string m_saveFile;
|
||||
std::string m_saveName;
|
||||
|
||||
private:
|
||||
static App::PropertyFloatConstraint::Constraints scaleRange;
|
||||
|
||||
@@ -539,7 +539,7 @@ Base::Vector3d DrawViewSection::getSectionVector (const std::string sectionName)
|
||||
std::vector<LineSet> DrawViewSection::getDrawableLines(int i)
|
||||
{
|
||||
std::vector<LineSet> result;
|
||||
result = DrawGeomHatch::getDrawableLines(this,m_lineSets,i,HatchScale.getValue());
|
||||
result = DrawGeomHatch::getTrimmedLines(this,m_lineSets,i,HatchScale.getValue());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,9 @@
|
||||
#include <stdexcept>
|
||||
#endif
|
||||
|
||||
#include <TopoDS_Vertex.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopExp.hxx>
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Vector3D.h>
|
||||
@@ -42,23 +44,80 @@
|
||||
|
||||
using namespace TechDraw;
|
||||
|
||||
HatchLine::HatchLine()
|
||||
double LineSet::getMinX(void)
|
||||
{
|
||||
double xMin,yMin,zMin,xMax,yMax,zMax;
|
||||
m_box.Get(xMin,yMin,zMin,xMax,yMax,zMax);
|
||||
return xMin;
|
||||
}
|
||||
|
||||
double LineSet::getMinY(void)
|
||||
{
|
||||
double xMin,yMin,zMin,xMax,yMax,zMax;
|
||||
m_box.Get(xMin,yMin,zMin,xMax,yMax,zMax);
|
||||
return yMin;
|
||||
}
|
||||
|
||||
double LineSet::getMaxX(void)
|
||||
{
|
||||
double xMin,yMin,zMin,xMax,yMax,zMax;
|
||||
m_box.Get(xMin,yMin,zMin,xMax,yMax,zMax);
|
||||
return xMax;
|
||||
}
|
||||
|
||||
double LineSet::getMaxY(void)
|
||||
{
|
||||
double xMin,yMin,zMin,xMax,yMax,zMax;
|
||||
m_box.Get(xMin,yMin,zMin,xMax,yMax,zMax);
|
||||
return yMax;
|
||||
}
|
||||
|
||||
bool LineSet::isDashed(void)
|
||||
{
|
||||
bool result = m_hatchLine.isDashed();
|
||||
return result;
|
||||
}
|
||||
|
||||
//TODO: needs to incorporate deltaX parameter
|
||||
//! calculates the apparent start point for dashed lines
|
||||
Base::Vector3d LineSet::calcApparentStart(TechDrawGeometry::BaseGeom* g)
|
||||
{
|
||||
Base::Vector3d result;
|
||||
Base::Vector3d start(g->getStartPoint().x,g->getStartPoint().y,0.0);
|
||||
double angle = getPATLineSpec().getAngle();
|
||||
if (angle == 0.0) { //horizontal
|
||||
result = Base::Vector3d(getMinX(),start.y,0.0);
|
||||
} else if ((angle == 90.0) ||
|
||||
(angle == -90.0)) { //vertical
|
||||
result = Base::Vector3d(start.x,getMinY(),0.0);
|
||||
} else {
|
||||
double slope = getPATLineSpec().getSlope();
|
||||
double y = getMinY();
|
||||
double x = ((y - start.y) / slope) + start.x;
|
||||
result = Base::Vector3d(x,y,0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//*******************************************
|
||||
PATLineSpec::PATLineSpec()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
HatchLine::HatchLine(std::string& lineSpec)
|
||||
PATLineSpec::PATLineSpec(std::string& lineSpec)
|
||||
{
|
||||
init();
|
||||
load(lineSpec);
|
||||
}
|
||||
|
||||
|
||||
HatchLine::~HatchLine()
|
||||
PATLineSpec::~PATLineSpec()
|
||||
{
|
||||
}
|
||||
|
||||
void HatchLine::init(void)
|
||||
void PATLineSpec::init(void)
|
||||
{
|
||||
m_angle = 0.0;
|
||||
m_origin = Base::Vector3d(0.0,0.0,0.0);
|
||||
@@ -66,11 +125,11 @@ void HatchLine::init(void)
|
||||
m_offset = 0.0;
|
||||
}
|
||||
|
||||
void HatchLine::load(std::string& lineSpec)
|
||||
void PATLineSpec::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() );
|
||||
Base::Console().Message( "PATLineSpec::load(%s) invalid entry in pattern\n",lineSpec.c_str() );
|
||||
return;
|
||||
}
|
||||
m_angle = values[0];
|
||||
@@ -78,11 +137,13 @@ void HatchLine::load(std::string& lineSpec)
|
||||
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> dash;
|
||||
dash.insert(std::end(dash), std::begin(values) + 5, std::end(values));
|
||||
m_dashParms = DashSpec(dash);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<double> HatchLine::split(std::string line)
|
||||
std::vector<double> PATLineSpec::split(std::string line)
|
||||
{
|
||||
std::vector<double> result;
|
||||
std::stringstream lineStream(line);
|
||||
@@ -101,25 +162,26 @@ std::vector<double> HatchLine::split(std::string line)
|
||||
return result;
|
||||
}
|
||||
|
||||
void HatchLine::dump(char* title)
|
||||
void PATLineSpec::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());
|
||||
// std::stringstream ss;
|
||||
// for (auto& d: m_dashParms) {
|
||||
// ss << d << ", ";
|
||||
// }
|
||||
// ss << "end";
|
||||
// Base::Console().Message( "DashSpec: %s\n",ss.str().c_str());
|
||||
m_dashParms.dump("dashspec");
|
||||
}
|
||||
|
||||
//static class methods
|
||||
std::vector<HatchLine> HatchLine::getSpecsForPattern(std::string& parmFile, std::string& parmName)
|
||||
std::vector<PATLineSpec> PATLineSpec::getSpecsForPattern(std::string& parmFile, std::string& parmName)
|
||||
{
|
||||
std::vector<HatchLine> result;
|
||||
std::vector<PATLineSpec> result;
|
||||
std::vector<std::string> lineSpecs;
|
||||
std::ifstream inFile;
|
||||
inFile.open (parmFile, std::ifstream::in);
|
||||
@@ -137,15 +199,15 @@ std::vector<HatchLine> HatchLine::getSpecsForPattern(std::string& parmFile, std:
|
||||
return result;
|
||||
}
|
||||
|
||||
//decode definition lines into HatchLine objects
|
||||
//decode definition lines into PATLineSpec objects
|
||||
for (auto& l: lineSpecs) {
|
||||
HatchLine hl(l);
|
||||
PATLineSpec hl(l);
|
||||
result.push_back(hl);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool HatchLine::findPatternStart(std::ifstream& inFile, std::string& parmName)
|
||||
bool PATLineSpec::findPatternStart(std::ifstream& inFile, std::string& parmName)
|
||||
{
|
||||
bool result = false;
|
||||
while ( inFile.good() ){
|
||||
@@ -176,7 +238,7 @@ bool HatchLine::findPatternStart(std::ifstream& inFile, std::string& parmName)
|
||||
}
|
||||
|
||||
//get the definition lines for this pattern
|
||||
std::vector<std::string> HatchLine::loadPatternDef(std::ifstream& inFile)
|
||||
std::vector<std::string> PATLineSpec::loadPatternDef(std::ifstream& inFile)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
while ( inFile.good() ){
|
||||
@@ -196,7 +258,7 @@ std::vector<std::string> HatchLine::loadPatternDef(std::ifstream& inFile)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> HatchLine::getPatternList(std::string& parmFile)
|
||||
std::vector<std::string> PATLineSpec::getPatternList(std::string& parmFile)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
std::ifstream inFile;
|
||||
@@ -225,6 +287,26 @@ std::vector<std::string> HatchLine::getPatternList(std::string& parmFile)
|
||||
return result;
|
||||
}
|
||||
|
||||
double PATLineSpec::getSlope(void)
|
||||
{
|
||||
double angle = 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);
|
||||
}
|
||||
double slope = tan(angle * M_PI/180.0);
|
||||
return slope;
|
||||
}
|
||||
|
||||
bool PATLineSpec::isDashed(void)
|
||||
{
|
||||
bool result = !m_dashParms.empty();
|
||||
return result;
|
||||
}
|
||||
|
||||
//********************************************************
|
||||
void DashSpec::dump(char* title)
|
||||
{
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
//! HatchLine - Classes related to processing PAT files
|
||||
|
||||
#ifndef _TechDraw_HATCHLINE_H_
|
||||
#define _TechDraw_HATCHLINE_H_
|
||||
@@ -29,9 +31,12 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <Bnd_Box.hxx>
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
class TopoDS_Edge;
|
||||
//class TopoDS_Edge;
|
||||
//class Bnd_Box;
|
||||
|
||||
namespace TechDrawGeometry
|
||||
{
|
||||
@@ -43,15 +48,32 @@ namespace TechDraw
|
||||
class DrawViewPart;
|
||||
class DrawUtil;
|
||||
|
||||
//DashSpec is the parsed portion of a PATLineSpec related to mark/space/dot
|
||||
class TechDrawExport 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();}
|
||||
double length(void);
|
||||
void dump(char* title);
|
||||
|
||||
private:
|
||||
std::vector<double> m_parms;
|
||||
};
|
||||
|
||||
// HatchLine is the result of parsing a line from PAT file into accessible parameters
|
||||
// e /HatchLine/PATSpecLine/
|
||||
class TechDrawExport HatchLine
|
||||
//! PATLineSpec is the result of parsing a singleline from PAT file into accessible parameters
|
||||
class TechDrawExport PATLineSpec
|
||||
{
|
||||
public:
|
||||
HatchLine();
|
||||
HatchLine(std::string& lineSpec);
|
||||
~HatchLine();
|
||||
PATLineSpec();
|
||||
PATLineSpec(std::string& lineSpec);
|
||||
~PATLineSpec();
|
||||
|
||||
void load(std::string& lineSpec);
|
||||
|
||||
@@ -61,10 +83,12 @@ public:
|
||||
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 std::vector<PATLineSpec> 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);
|
||||
|
||||
bool isDashed(void);
|
||||
|
||||
void dump(char* title);
|
||||
|
||||
@@ -76,48 +100,45 @@ private:
|
||||
Base::Vector3d m_origin;
|
||||
double m_interval;
|
||||
double m_offset;
|
||||
std::vector<double> m_dashParms; //why isn't this a DashSpec object?
|
||||
DashSpec m_dashParms;
|
||||
};
|
||||
|
||||
// a LineSet is all the generated edges for 1 HatchLine for 1 Face
|
||||
//! a LineSet is all the generated edges for 1 PATLineSpec for 1 Face
|
||||
class TechDrawExport LineSet
|
||||
{
|
||||
public:
|
||||
LineSet() {}
|
||||
~LineSet() {}
|
||||
|
||||
void setHatchLine(HatchLine s) { m_hatchLine = s; }
|
||||
void setPATLineSpec(PATLineSpec s) { m_hatchLine = s; }
|
||||
void setEdges(std::vector<TopoDS_Edge> e) {m_edges = e;}
|
||||
void setGeoms(std::vector<TechDrawGeometry::BaseGeom*> g) {m_geoms = g;}
|
||||
void setBBox(Bnd_Box bb) {m_box = bb;}
|
||||
|
||||
HatchLine getHatchLine(void) { return m_hatchLine; }
|
||||
std::vector<double> getDashSpec(void) { return m_hatchLine.getDashParms();}
|
||||
PATLineSpec getPATLineSpec(void) { return m_hatchLine; }
|
||||
double getOffset(void) { return m_hatchLine.getOffset(); }
|
||||
double getAngle(void) { return m_hatchLine.getAngle(); }
|
||||
DashSpec getDashSpec(void) { return m_hatchLine.getDashParms();}
|
||||
std::vector<TopoDS_Edge> getEdges(void) { return m_edges; }
|
||||
TopoDS_Edge getEdge(int i) {return m_edges.at(i);}
|
||||
std::vector<TechDrawGeometry::BaseGeom*> getGeoms(void) { return m_geoms; }
|
||||
//void clearGeom(void);
|
||||
Base::Vector3d calcApparentStart(TechDrawGeometry::BaseGeom* g);
|
||||
|
||||
Bnd_Box getBBox(void) {return m_box;}
|
||||
double getMinX(void);
|
||||
double getMaxX(void);
|
||||
double getMinY(void);
|
||||
double getMaxY(void);
|
||||
|
||||
bool isDashed(void);
|
||||
|
||||
private:
|
||||
std::vector<TopoDS_Edge> m_edges;
|
||||
std::vector<TechDrawGeometry::BaseGeom*> m_geoms;
|
||||
HatchLine m_hatchLine;
|
||||
PATLineSpec m_hatchLine;
|
||||
Bnd_Box m_box;
|
||||
};
|
||||
|
||||
class TechDrawExport 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
|
||||
|
||||
|
||||
@@ -175,13 +175,13 @@ void CmdTechDrawNewGeomHatch::activated(int iMsg)
|
||||
geomhatch->Source.setValue(objFeat, subNames);
|
||||
Gui::ViewProvider* vp = Gui::Application::Instance->getDocument(getDocument())->getViewProvider(geomhatch);
|
||||
TechDrawGui::ViewProviderGeomHatch* hvp = dynamic_cast<TechDrawGui::ViewProviderGeomHatch*>(vp);
|
||||
if( hvp == nullptr ) {
|
||||
if (!hvp) {
|
||||
Base::Console().Log("ERROR - CommandDecorate - GeomHatch has no ViewProvider\n");
|
||||
return;
|
||||
}
|
||||
// if (!hvp) {
|
||||
|
||||
// dialog to fill in hatch values
|
||||
Gui::Control().showDialog(new TaskDlgGeomHatch(geomhatch,hvp));
|
||||
Gui::Control().showDialog(new TaskDlgGeomHatch(geomhatch,hvp,true));
|
||||
|
||||
|
||||
commitCommand();
|
||||
|
||||
@@ -41,6 +41,10 @@
|
||||
#include <QRectF>
|
||||
#include <QPointF>
|
||||
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsView>
|
||||
#include <QTransform>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <App/Application.h>
|
||||
@@ -50,9 +54,14 @@
|
||||
|
||||
#include <Mod/TechDraw/App/DrawUtil.h>
|
||||
|
||||
//debug
|
||||
#include "QGICMark.h"
|
||||
#include "ZVALUE.h"
|
||||
//
|
||||
#include "Rez.h"
|
||||
#include "QGCustomSvg.h"
|
||||
#include "QGCustomRect.h"
|
||||
#include "QGIViewPart.h"
|
||||
#include "QGIFace.h"
|
||||
|
||||
using namespace TechDrawGui;
|
||||
@@ -66,7 +75,8 @@ QGIFace::QGIFace(int index) :
|
||||
{
|
||||
setFillMode(NoFill);
|
||||
isHatched(false);
|
||||
setFlag(QGraphicsItem::ItemClipsChildrenToShape,true);
|
||||
// setFlag(QGraphicsItem::ItemClipsChildrenToShape,true);
|
||||
setFlag(QGraphicsItem::ItemClipsChildrenToShape,false);
|
||||
|
||||
//setStyle(Qt::NoPen); //don't draw face lines, just fill for debugging
|
||||
setStyle(Qt::DashLine);
|
||||
@@ -99,18 +109,13 @@ void QGIFace::draw()
|
||||
setPath(m_outline); //Face boundary
|
||||
|
||||
if (isHatched()) {
|
||||
if (m_mode == GeomHatchFill) { //crosshatch
|
||||
if (!m_geomHatchPaths.empty()) { //surrogate for LineSets.empty
|
||||
if (m_mode == GeomHatchFill) {
|
||||
if (!m_lineSets.empty()) {
|
||||
m_brush.setTexture(QPixmap());
|
||||
m_fillStyle = m_styleDef;
|
||||
m_styleNormal = m_fillStyle;
|
||||
int pathNo = 0;
|
||||
for (auto& pp: m_geomHatchPaths) {
|
||||
QGraphicsPathItem* fillItem = m_fillItems.at(pathNo);
|
||||
fillItem->setPath(pp);
|
||||
QPen geomPen = setGeomPen(pathNo);
|
||||
fillItem->setPen(geomPen);
|
||||
pathNo++;
|
||||
for (auto& ls: m_lineSets) {
|
||||
lineSetToFillItem(ls);
|
||||
}
|
||||
}
|
||||
} else if ((m_mode == FromFile) ||
|
||||
@@ -217,27 +222,121 @@ void QGIFace::setOutline(const QPainterPath & path)
|
||||
|
||||
void QGIFace::clearLineSets(void)
|
||||
{
|
||||
m_geomHatchPaths.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)
|
||||
void QGIFace::addLineSet(LineSet ls)
|
||||
{
|
||||
m_geomHatchPaths.push_back(pp);
|
||||
m_dashSpecs.push_back(DashSpec(dp));
|
||||
addFillItem();
|
||||
}
|
||||
m_lineSets.push_back(ls);
|
||||
}
|
||||
|
||||
QGraphicsPathItem* QGIFace::addFillItem()
|
||||
void QGIFace::lineSetToFillItem(LineSet ls)
|
||||
{
|
||||
QGraphicsPathItem* fillItem = new QGraphicsPathItem();
|
||||
fillItem->setParentItem(this);
|
||||
for (auto& g: ls.getGeoms()) {
|
||||
QGraphicsLineItem* fillItem = geomToLine(g);
|
||||
QPen geomPen = setGeomPen(ls.getDashSpec());
|
||||
if (ls.isDashed()) {
|
||||
double offset = calcOffset(g,ls); //offset in graphics coords(?)
|
||||
geomPen.setDashOffset(offset);
|
||||
// geomPen.setDashOffset(offset/getXForm()); //try to account for QGraphicsView Zoom level
|
||||
}
|
||||
fillItem->setPen(geomPen);
|
||||
}
|
||||
}
|
||||
|
||||
QGraphicsLineItem* QGIFace::geomToLine(TechDrawGeometry::BaseGeom* base)
|
||||
{
|
||||
QGraphicsLineItem* fillItem = new QGraphicsLineItem(this);
|
||||
fillItem->setLine(Rez::guiX(base->getStartPoint().x),
|
||||
Rez::guiX(-base->getStartPoint().y),
|
||||
Rez::guiX(base->getEndPoint().x),
|
||||
Rez::guiX(-base->getEndPoint().y));
|
||||
m_fillItems.push_back(fillItem);
|
||||
return fillItem;
|
||||
}
|
||||
|
||||
|
||||
QPen QGIFace::setGeomPen(DashSpec ourSpec)
|
||||
{
|
||||
QPen result;
|
||||
result.setWidthF(Rez::guiX(m_geomWeight));
|
||||
// result.setWidthF(1.0);
|
||||
result.setColor(m_geomColor);
|
||||
if (ourSpec.empty()) {
|
||||
result.setStyle(Qt::SolidLine);
|
||||
} else {
|
||||
result.setStyle(Qt::CustomDashLine);
|
||||
result.setDashPattern(decodeDashSpec(ourSpec));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double QGIFace::calcOffset(TechDrawGeometry::BaseGeom* g,LineSet ls)
|
||||
{
|
||||
Base::Vector3d startPoint(g->getStartPoint().x,g->getStartPoint().y,0.0);
|
||||
Base::Vector3d appStart = ls.calcApparentStart(g);
|
||||
double distToStart = (startPoint - appStart).Length();
|
||||
double patternLength = ls.getDashSpec().length();
|
||||
|
||||
double penWidth = Rez::guiX(m_geomWeight);
|
||||
// double penWidth = 1.0;
|
||||
distToStart = Rez::guiX(distToStart); //distance in scene units/pixels?
|
||||
patternLength = Rez::guiX(patternLength) * penWidth; //pattern as it will be rendered by QPen (length*weight)
|
||||
double patternReps = distToStart / patternLength;
|
||||
double remain = patternReps - floor(patternReps); //fraction of a pattern
|
||||
double result = patternLength * remain;
|
||||
return result;
|
||||
}
|
||||
|
||||
//!convert from PAT style "-1,0,-1,+1" in mm to Qt style "mark,space,mark,space" in penWidths
|
||||
// the actual dash pattern/offset varies according to lineWeight, GraphicsView zoom level, scene unit size (and printer scale?).
|
||||
// haven't figured out the actual algorithm.
|
||||
// in Qt a dash length of l (8) with a pen of width w (2) yields a dash of length l*w (16), but this is only part of the equation.
|
||||
QVector<qreal> QGIFace::decodeDashSpec(DashSpec patDash)
|
||||
{
|
||||
double penWidth = Rez::guiX(m_geomWeight);
|
||||
double minPen = 0.01; //avoid trouble with cosmetic pen (zero width)?
|
||||
if (penWidth <= minPen) {
|
||||
penWidth = minPen;
|
||||
}
|
||||
double unitLength = penWidth;
|
||||
// double unitLength = 1.0;
|
||||
std::vector<double> result;
|
||||
for (auto& d: patDash.get()) {
|
||||
double strokeLength;
|
||||
if (DrawUtil::fpCompare(d,0.0)) { //pat dot
|
||||
strokeLength = unitLength;
|
||||
} else if (Rez::guiX(d) < 0) { //pat space
|
||||
strokeLength = fabs(Rez::guiX(d)) / unitLength;
|
||||
} else { //pat dash
|
||||
strokeLength = Rez::guiX(d) / unitLength;
|
||||
}
|
||||
// //try to keep the pattern the same when View scales
|
||||
// strokeLength = strokeLength/getXForm();
|
||||
// Base::Console().Message("TRACE - QGIF - d: %.3f strokeLength: %.3f\n",d,strokeLength);
|
||||
result.push_back(strokeLength);
|
||||
}
|
||||
|
||||
return QVector<qreal>::fromStdVector( result );
|
||||
}
|
||||
|
||||
//! get zoom level (scale) from QGraphicsView
|
||||
double QGIFace::getXForm(void)
|
||||
{
|
||||
//try to keep the pattern the same when View scales
|
||||
double result = 1.0;
|
||||
auto s = scene();
|
||||
if (s) {
|
||||
auto vs = s->views(); //ptrs to views
|
||||
if (!vs.empty()) {
|
||||
auto v = vs.at(0);
|
||||
auto i = v->transform().inverted();
|
||||
result = i.m11();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void QGIFace::clearFillItems(void)
|
||||
{
|
||||
for (auto& f: m_fillItems) {
|
||||
@@ -247,48 +346,14 @@ void QGIFace::clearFillItems(void)
|
||||
}
|
||||
}
|
||||
|
||||
//convert from PAT style "-1,0,-1,+1" to Qt style "mark,space,mark,space"
|
||||
QVector<qreal> QGIFace::decodeDashSpec(DashSpec patDash)
|
||||
void QGIFace::makeMark(double x, double y)
|
||||
{
|
||||
//Rez::guiX(something)?
|
||||
double dotLength = 3.0;
|
||||
double unitLength = 6.0;
|
||||
// double penWidth = m_geomWeight; //mark, space and dot lengths are to be in terms of penWidth(Qt) or mm(PAT)??
|
||||
// //if we want it in terms of mm, we need to divide by penWidth?
|
||||
// double minPen = 0.01; //avoid trouble with cosmetic pen (zero width)
|
||||
std::vector<double> result;
|
||||
std::string prim;
|
||||
for (auto& d: patDash.get()) {
|
||||
double strokeLength;
|
||||
if (DrawUtil::fpCompare(d,0.0)) { //pat dot
|
||||
strokeLength = dotLength;
|
||||
} else if (Rez::guiX(d) < 0) { //pat space
|
||||
strokeLength = fabs(Rez::guiX(d)) * unitLength;
|
||||
} else { //pat dash
|
||||
strokeLength = Rez::guiX(d) * unitLength;
|
||||
}
|
||||
result.push_back(strokeLength);
|
||||
}
|
||||
return QVector<qreal>::fromStdVector( result );
|
||||
}
|
||||
|
||||
|
||||
QPen QGIFace::setGeomPen(int i)
|
||||
{
|
||||
//m_dashSpecs[i].dump("spec test");
|
||||
DashSpec ourSpec = m_dashSpecs.at(i);
|
||||
//ourSpec.dump("our spec");
|
||||
|
||||
QPen result;
|
||||
result.setWidthF(Rez::guiX(m_geomWeight)); //Rez::guiX() ?? line weights are in mm?
|
||||
result.setColor(m_geomColor);
|
||||
if (ourSpec.empty()) {
|
||||
result.setStyle(Qt::SolidLine);
|
||||
} else {
|
||||
result.setStyle(Qt::CustomDashLine);
|
||||
result.setDashPattern(decodeDashSpec(ourSpec));
|
||||
}
|
||||
return result;
|
||||
QGICMark* cmItem = new QGICMark(-1);
|
||||
cmItem->setParentItem(this);
|
||||
cmItem->setPos(x,y);
|
||||
cmItem->setThick(0.5);
|
||||
cmItem->setSize(2.0);
|
||||
cmItem->setZValue(ZVALUE::VERTEX);
|
||||
}
|
||||
|
||||
void QGIFace::buildSvgHatch()
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <QPixmap>
|
||||
|
||||
#include <Mod/TechDraw/App/HatchLine.h>
|
||||
#include <Mod/TechDraw/App/Geometry.h>
|
||||
|
||||
#include "QGIPrimPath.h"
|
||||
|
||||
@@ -101,17 +102,25 @@ public:
|
||||
|
||||
//PAT fill parms & methods
|
||||
void setGeomHatchWeight(double w) { m_geomWeight = w; }
|
||||
void clearLineSets(void);
|
||||
void addLineSet(QPainterPath pp, std::vector<double> dp);
|
||||
QGraphicsPathItem* addFillItem();
|
||||
void clearFillItems(void);
|
||||
void setLineWeight(double w);
|
||||
|
||||
void clearLineSets(void);
|
||||
void addLineSet(LineSet ls);
|
||||
void clearFillItems(void);
|
||||
|
||||
void lineSetToFillItem(LineSet ls);
|
||||
QGraphicsLineItem* geomToLine(TechDrawGeometry::BaseGeom* base);
|
||||
double calcOffset(TechDrawGeometry::BaseGeom* g,LineSet ls);
|
||||
|
||||
//bitmap texture fill parms method
|
||||
QPixmap textureFromBitmap(std::string fileSpec);
|
||||
QPixmap textureFromSvg(std::string fillSpec);
|
||||
|
||||
protected:
|
||||
void makeMark(double x, double y);
|
||||
double getXForm(void);
|
||||
|
||||
|
||||
int projIndex; //index of face in Projection. -1 for SectionFace.
|
||||
QGCustomRect *m_rect;
|
||||
|
||||
@@ -124,10 +133,10 @@ protected:
|
||||
bool m_isHatched;
|
||||
QGIFace::fillMode m_mode;
|
||||
|
||||
QPen setGeomPen(int i);
|
||||
QPen setGeomPen(DashSpec ds);
|
||||
QVector<qreal> decodeDashSpec(DashSpec d);
|
||||
std::vector<QGraphicsPathItem*> m_fillItems;
|
||||
std::vector<QPainterPath> m_geomHatchPaths; // 0/1 dashspec per hatchpath
|
||||
std::vector<QGraphicsLineItem*> m_fillItems;
|
||||
std::vector<LineSet> m_lineSets;
|
||||
std::vector<DashSpec> m_dashSpecs;
|
||||
|
||||
|
||||
|
||||
@@ -83,9 +83,9 @@ void QGIPrimPath::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||
|
||||
void QGIPrimPath::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
|
||||
{
|
||||
QGIView *view = dynamic_cast<QGIView *> (parentItem()); //this is temp for debug??
|
||||
assert(view != 0);
|
||||
Q_UNUSED(view);
|
||||
// QGIView *view = dynamic_cast<QGIView *> (parentItem()); //this is temp for debug??
|
||||
// assert(view != 0);
|
||||
// Q_UNUSED(view);
|
||||
if(!isSelected() && !isHighlighted) {
|
||||
setPrettyNormal();
|
||||
}
|
||||
|
||||
@@ -138,6 +138,13 @@ void QGIViewPart::setViewPartFeature(TechDraw::DrawViewPart *obj)
|
||||
}
|
||||
|
||||
QPainterPath QGIViewPart::drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom) const
|
||||
{
|
||||
double rot = getViewObject()->Rotation.getValue();
|
||||
return geomToPainterPath(baseGeom,rot);
|
||||
}
|
||||
|
||||
|
||||
QPainterPath QGIViewPart::geomToPainterPath(TechDrawGeometry::BaseGeom *baseGeom, double rot)
|
||||
{
|
||||
QPainterPath path;
|
||||
|
||||
@@ -152,7 +159,6 @@ QPainterPath QGIViewPart::drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom)
|
||||
Rez::guiX(y),
|
||||
Rez::guiX(geom->radius * 2),
|
||||
Rez::guiX(geom->radius * 2)); //topleft@(x,y) radx,rady
|
||||
//Base::Console().Message("TRACE -drawPainterPath - making an CIRCLE @(%.3f,%.3f) R:%.3f\n",x, y, geom->radius);
|
||||
} break;
|
||||
case TechDrawGeometry::ARCOFCIRCLE: {
|
||||
TechDrawGeometry::AOC *geom = static_cast<TechDrawGeometry::AOC *>(baseGeom);
|
||||
@@ -167,9 +173,6 @@ QPainterPath QGIViewPart::drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom)
|
||||
Rez::guiX(geom->endPnt.y),
|
||||
Rez::guiX(geom->startPnt.x),
|
||||
Rez::guiX(geom->startPnt.y));
|
||||
// double x = geom->center.x - geom->radius;
|
||||
// double y = geom->center.y - geom->radius;
|
||||
//Base::Console().Message("TRACE -drawPainterPath - making an ARCOFCIRCLE @(%.3f,%.3f) R:%.3f\n",x, y, geom->radius);
|
||||
} break;
|
||||
case TechDrawGeometry::ELLIPSE: {
|
||||
TechDrawGeometry::Ellipse *geom = static_cast<TechDrawGeometry::Ellipse *>(baseGeom);
|
||||
@@ -202,7 +205,6 @@ QPainterPath QGIViewPart::drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom)
|
||||
Rez::guiX(endX),
|
||||
Rez::guiX(endY));
|
||||
|
||||
//Base::Console().Message("TRACE -drawPainterPath - making an ELLIPSE @(%.3f,%.3f) R1:%.3f R2:%.3f\n",geom->center.x,geom->center.y, geom->major, geom->minor);
|
||||
} break;
|
||||
case TechDrawGeometry::ARCOFELLIPSE: {
|
||||
TechDrawGeometry::AOE *geom = static_cast<TechDrawGeometry::AOE *>(baseGeom);
|
||||
@@ -217,7 +219,6 @@ QPainterPath QGIViewPart::drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom)
|
||||
Rez::guiX(geom->endPnt.y),
|
||||
Rez::guiX(geom->startPnt.x),
|
||||
Rez::guiX(geom->startPnt.y));
|
||||
//Base::Console().Message("TRACE -drawPainterPath - making an ARCOFELLIPSE R1:%.3f R2:%.3f From: (%.3f,%.3f) To: (%.3f,%.3f)\n",geom->major, geom->minor,geom->startPnt.x, geom->startPnt.y,geom->endPnt.x, geom->endPnt.y);
|
||||
|
||||
} break;
|
||||
case TechDrawGeometry::BEZIER: {
|
||||
@@ -225,7 +226,6 @@ QPainterPath QGIViewPart::drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom)
|
||||
|
||||
// Move painter to the beginning
|
||||
path.moveTo(Rez::guiX(geom->pnts[0].x), Rez::guiX(geom->pnts[0].y));
|
||||
//Base::Console().Message("TRACE -drawPainterPath - making an BEZIER From: (%.3f,%.3f)\n",geom->pnts[0].x,geom->pnts[0].y);
|
||||
|
||||
if ( geom->poles == 2 ) {
|
||||
// Degree 1 bezier = straight line...
|
||||
@@ -254,7 +254,6 @@ QPainterPath QGIViewPart::drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom)
|
||||
|
||||
// Move painter to the beginning of our first segment
|
||||
path.moveTo(Rez::guiX(it->pnts[0].x), Rez::guiX(it->pnts[0].y));
|
||||
//Base::Console().Message("TRACE -drawPainterPath - making an BSPLINE From: (%.3f,%.3f)\n",it->pnts[0].x,it->pnts[0].y);
|
||||
|
||||
for ( ; it != geom->segments.end(); ++it) {
|
||||
// At this point, the painter is either at the beginning
|
||||
@@ -282,19 +281,16 @@ QPainterPath QGIViewPart::drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom)
|
||||
|
||||
path.moveTo(Rez::guiX(geom->points[0].x), Rez::guiX(geom->points[0].y));
|
||||
std::vector<Base::Vector2d>::const_iterator it = geom->points.begin();
|
||||
//Base::Console().Message("TRACE -drawPainterPath - making an GENERIC From: (%.3f,%.3f)\n",geom->points[0].x, geom->points[0].y);
|
||||
for(++it; it != geom->points.end(); ++it) {
|
||||
path.lineTo(Rez::guiX((*it).x), Rez::guiX((*it).y));
|
||||
//Base::Console().Message(">>>> To: (%.3f,%.3f)\n",(*it).x, (*it).y);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
Base::Console().Error("Error - drawPainterPath - UNKNOWN geomType: %d\n",baseGeom->geomType);
|
||||
Base::Console().Error("Error - geomToPainterPath - UNKNOWN geomType: %d\n",baseGeom->geomType);
|
||||
break;
|
||||
}
|
||||
|
||||
double rot = getViewObject()->Rotation.getValue();
|
||||
if (rot) {
|
||||
if (rot != 0.0) {
|
||||
QTransform t;
|
||||
t.rotate(-rot);
|
||||
path = t.map(path);
|
||||
@@ -391,16 +387,11 @@ void QGIViewPart::drawViewPart()
|
||||
const std::vector<std::string> &sourceNames = fGeom->Source.getSubValues();
|
||||
if (!sourceNames.empty()) {
|
||||
int fdx = TechDraw::DrawUtil::getIndexFromName(sourceNames.at(0));
|
||||
std::vector<LineSet> lineSets = fGeom->getDrawableLines(fdx);
|
||||
std::vector<LineSet> lineSets = fGeom->getTrimmedLines(fdx);
|
||||
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->addLineSet(ls);
|
||||
}
|
||||
newFace->isHatched(true);
|
||||
newFace->setFillMode(QGIFace::GeomHatchFill);
|
||||
@@ -555,7 +546,6 @@ void QGIViewPart::removePrimitives()
|
||||
if (prim) {
|
||||
removeFromGroup(prim);
|
||||
scene()->removeItem(prim);
|
||||
// deleteItems.append(prim); //pretty sure we could just delete here since not in scene anymore
|
||||
delete prim;
|
||||
}
|
||||
}
|
||||
@@ -722,7 +712,7 @@ void QGIViewPart::drawMatting()
|
||||
void QGIViewPart::pathArc(QPainterPath &path, double rx, double ry, double x_axis_rotation,
|
||||
bool large_arc_flag, bool sweep_flag,
|
||||
double x, double y,
|
||||
double curx, double cury) const
|
||||
double curx, double cury)
|
||||
{
|
||||
double sin_th, cos_th;
|
||||
double a00, a01, a10, a11;
|
||||
@@ -804,7 +794,7 @@ void QGIViewPart::pathArc(QPainterPath &path, double rx, double ry, double x_axi
|
||||
void QGIViewPart::pathArcSegment(QPainterPath &path,
|
||||
double xc, double yc,
|
||||
double th0, double th1,
|
||||
double rx, double ry, double xAxisRotation) const
|
||||
double rx, double ry, double xAxisRotation)
|
||||
{
|
||||
double sinTh, cosTh;
|
||||
double a00, a01, a10, a11;
|
||||
|
||||
@@ -66,23 +66,24 @@ public:
|
||||
|
||||
virtual void draw() override;
|
||||
|
||||
protected:
|
||||
static QPainterPath geomToPainterPath(TechDrawGeometry::BaseGeom *baseGeom, double rotation = 0.0);
|
||||
/// Helper for pathArc()
|
||||
/*!
|
||||
* x_axis_rotation is in radian
|
||||
*/
|
||||
void pathArcSegment(QPainterPath &path, double xc, double yc, double th0,
|
||||
double th1,double rx, double ry, double xAxisRotation) const;
|
||||
static void pathArcSegment(QPainterPath &path, double xc, double yc, double th0,
|
||||
double th1,double rx, double ry, double xAxisRotation);
|
||||
|
||||
/// Draws an arc using QPainterPath path
|
||||
/*!
|
||||
* x_axis_rotation is in radian
|
||||
*/
|
||||
void pathArc(QPainterPath &path, double rx, double ry, double x_axis_rotation,
|
||||
static void pathArc(QPainterPath &path, double rx, double ry, double x_axis_rotation,
|
||||
bool large_arc_flag, bool sweep_flag,
|
||||
double x, double y,
|
||||
double curx, double cury) const;
|
||||
double curx, double cury);
|
||||
|
||||
protected:
|
||||
QPainterPath drawPainterPath(TechDrawGeometry::BaseGeom *baseGeom) const;
|
||||
void drawViewPart();
|
||||
QGIFace* drawFace(TechDrawGeometry::Face* f, int idx);
|
||||
|
||||
@@ -119,12 +119,12 @@ void QGIViewSection::drawSectionFace()
|
||||
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());
|
||||
// QPainterPath bigPath;
|
||||
// for (auto& g: ls.getGeoms()) {
|
||||
// QPainterPath smallPath = drawPainterPath(g);
|
||||
// bigPath.addPath(smallPath);
|
||||
// }
|
||||
newFace->addLineSet(ls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,10 +52,11 @@ using namespace Gui;
|
||||
using namespace TechDraw;
|
||||
using namespace TechDrawGui;
|
||||
|
||||
TaskGeomHatch::TaskGeomHatch(TechDraw::DrawGeomHatch* inHatch,TechDrawGui::ViewProviderGeomHatch* inVp) :
|
||||
TaskGeomHatch::TaskGeomHatch(TechDraw::DrawGeomHatch* inHatch,TechDrawGui::ViewProviderGeomHatch* inVp,bool mode) :
|
||||
ui(new Ui_TaskGeomHatch),
|
||||
m_hatch(inHatch),
|
||||
m_Vp(inVp)
|
||||
m_Vp(inVp),
|
||||
m_createMode(mode)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
connect(ui->fcFile, SIGNAL(fileNameSelected( const QString & )), this, SLOT(onFileChanged(void)));
|
||||
@@ -77,6 +78,12 @@ void TaskGeomHatch::initUi()
|
||||
std::vector<std::string> names = HatchLine::getPatternList(m_file);
|
||||
QStringList qsNames = listToQ(names);
|
||||
ui->cbName->addItems(qsNames);
|
||||
int nameIndex = ui->cbName->findText(QString::fromUtf8(m_name.data(),m_name.size()));
|
||||
if (nameIndex > -1) {
|
||||
ui->cbName->setCurrentIndex(nameIndex);
|
||||
} else {
|
||||
Base::Console().Warning("Warning - Pattern name not found in current PAT File\n");
|
||||
}
|
||||
ui->sbScale->setValue(m_scale);
|
||||
ui->sbWeight->setValue(m_weight);
|
||||
ui->ccColor->setColor(m_color.asValue<QColor>());
|
||||
@@ -121,16 +128,27 @@ bool TaskGeomHatch::accept()
|
||||
{
|
||||
updateValues();
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
|
||||
m_source->touch();
|
||||
m_source->getDocument()->recompute(); //TODO: this is only here to get graphics to update.
|
||||
// sb "redraw graphics" since m_source geom has not changed.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TaskGeomHatch::reject()
|
||||
{
|
||||
std::string HatchName = m_hatch->getNameInDocument();
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().removeObject('%s')",HatchName.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
|
||||
m_source->touch();
|
||||
m_source->getDocument()->recompute();
|
||||
if (getCreateMode()) {
|
||||
std::string HatchName = m_hatch->getNameInDocument();
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"App.activeDocument().removeObject('%s')",HatchName.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Gui,"Gui.ActiveDocument.resetEdit()");
|
||||
m_source->touch();
|
||||
m_source->getDocument()->recompute();
|
||||
} else {
|
||||
m_hatch->FilePattern.setValue(m_origFile);
|
||||
m_hatch->NamePattern.setValue(m_origName);
|
||||
m_hatch->ScalePattern.setValue(m_origScale);
|
||||
m_Vp->ColorPattern.setValue(m_origColor);
|
||||
m_Vp->WeightPattern.setValue(m_origWeight);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -141,6 +159,14 @@ void TaskGeomHatch::getParameters()
|
||||
m_scale = m_hatch->ScalePattern.getValue();
|
||||
m_color = m_Vp->ColorPattern.getValue();
|
||||
m_weight = m_Vp->WeightPattern.getValue();
|
||||
if (!getCreateMode()) {
|
||||
m_origFile = m_hatch->FilePattern.getValue();
|
||||
m_origName = m_hatch->NamePattern.getValue();
|
||||
m_origScale = m_hatch->ScalePattern.getValue();
|
||||
m_origColor = m_Vp->ColorPattern.getValue();
|
||||
m_origWeight = m_Vp->WeightPattern.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TaskGeomHatch::changeEvent(QEvent *e)
|
||||
@@ -151,10 +177,11 @@ void TaskGeomHatch::changeEvent(QEvent *e)
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
TaskDlgGeomHatch::TaskDlgGeomHatch(TechDraw::DrawGeomHatch* inHatch, TechDrawGui::ViewProviderGeomHatch* inVp) :
|
||||
TaskDialog()
|
||||
TaskDlgGeomHatch::TaskDlgGeomHatch(TechDraw::DrawGeomHatch* inHatch, TechDrawGui::ViewProviderGeomHatch* inVp, bool mode) :
|
||||
TaskDialog(),
|
||||
viewProvider(nullptr)
|
||||
{
|
||||
widget = new TaskGeomHatch(inHatch,inVp);
|
||||
widget = new TaskGeomHatch(inHatch,inVp, mode);
|
||||
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("TechDraw_Tree_View"),
|
||||
widget->windowTitle(), true, 0);
|
||||
taskbox->groupLayout()->addWidget(widget);
|
||||
@@ -165,6 +192,11 @@ TaskDlgGeomHatch::~TaskDlgGeomHatch()
|
||||
{
|
||||
}
|
||||
|
||||
void TaskDlgGeomHatch::setCreateMode(bool b)
|
||||
{
|
||||
widget->setCreateMode(b);
|
||||
}
|
||||
|
||||
void TaskDlgGeomHatch::update()
|
||||
{
|
||||
//widget->updateTask();
|
||||
|
||||
@@ -49,12 +49,14 @@ class TaskGeomHatch : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TaskGeomHatch(TechDraw::DrawGeomHatch* inHatch,TechDrawGui::ViewProviderGeomHatch* inVp);
|
||||
TaskGeomHatch(TechDraw::DrawGeomHatch* inHatch,TechDrawGui::ViewProviderGeomHatch* inVp, bool mode);
|
||||
~TaskGeomHatch();
|
||||
|
||||
public:
|
||||
virtual bool accept();
|
||||
virtual bool reject();
|
||||
void setCreateMode(bool b) { m_createMode = b;}
|
||||
bool getCreateMode() { return m_createMode; }
|
||||
|
||||
protected Q_SLOTS:
|
||||
void onFileChanged(void);
|
||||
@@ -77,6 +79,13 @@ private:
|
||||
double m_scale;
|
||||
double m_weight;
|
||||
App::Color m_color;
|
||||
std::string m_origFile;
|
||||
std::string m_origName;
|
||||
double m_origScale;
|
||||
double m_origWeight;
|
||||
App::Color m_origColor;
|
||||
|
||||
bool m_createMode;
|
||||
|
||||
};
|
||||
|
||||
@@ -85,8 +94,9 @@ class TaskDlgGeomHatch : public Gui::TaskView::TaskDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TaskDlgGeomHatch(TechDraw::DrawGeomHatch* inHatch,TechDrawGui::ViewProviderGeomHatch* inVp);
|
||||
TaskDlgGeomHatch(TechDraw::DrawGeomHatch* inHatch,TechDrawGui::ViewProviderGeomHatch* inVp, bool mode);
|
||||
~TaskDlgGeomHatch();
|
||||
const ViewProviderGeomHatch * getViewProvider() const { return viewProvider; }
|
||||
|
||||
public:
|
||||
/// is called the TaskView when the dialog is opened
|
||||
@@ -101,10 +111,12 @@ public:
|
||||
virtual void helpRequested() { return;}
|
||||
virtual bool isAllowedAlterDocument(void) const
|
||||
{ return false; }
|
||||
void setCreateMode(bool b);
|
||||
|
||||
void update();
|
||||
|
||||
protected:
|
||||
const ViewProviderGeomHatch *viewProvider;
|
||||
|
||||
private:
|
||||
TaskGeomHatch * widget;
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
#include <Mod/TechDraw/App/DrawGeomHatch.h>
|
||||
#include <Mod/TechDraw/App/DrawViewPart.h>
|
||||
#include <Mod/TechDraw/App/DrawView.h>
|
||||
#include "TaskGeomHatch.h"
|
||||
#include "ViewProviderDrawingView.h"
|
||||
#include "ViewProviderGeomHatch.h"
|
||||
|
||||
@@ -98,23 +99,53 @@ std::vector<std::string> ViewProviderGeomHatch::getDisplayModes(void) const
|
||||
return StrList;
|
||||
}
|
||||
|
||||
//for VP properties
|
||||
void ViewProviderGeomHatch::onChanged(const App::Property* prop)
|
||||
bool ViewProviderGeomHatch::setEdit(int ModNum)
|
||||
{
|
||||
if (prop == &WeightPattern ||
|
||||
prop == &ColorPattern ) {
|
||||
updateGraphic();
|
||||
Q_UNUSED(ModNum);
|
||||
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
|
||||
TaskDlgGeomHatch *projDlg = qobject_cast<TaskDlgGeomHatch *>(dlg);
|
||||
if (projDlg && (projDlg->getViewProvider() != this))
|
||||
projDlg = 0; // somebody left task panel open
|
||||
|
||||
// clear the selection (convenience)
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
// start the edit dialog
|
||||
if (projDlg) {
|
||||
projDlg->setCreateMode(false);
|
||||
Gui::Control().showDialog(projDlg);
|
||||
} else {
|
||||
Gui::Control().showDialog(new TaskDlgGeomHatch(getViewObject(),this,false));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewProviderGeomHatch::unsetEdit(int ModNum)
|
||||
{
|
||||
if (ModNum == ViewProvider::Default) {
|
||||
Gui::Control().closeDialog();
|
||||
}
|
||||
else {
|
||||
ViewProviderDocumentObject::unsetEdit(ModNum);
|
||||
}
|
||||
}
|
||||
|
||||
bool ViewProviderGeomHatch::doubleClicked(void)
|
||||
{
|
||||
setEdit(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
//for VP properties - but each letter/digit in property editor triggers this!
|
||||
void ViewProviderGeomHatch::onChanged(const App::Property* prop)
|
||||
{
|
||||
Gui::ViewProviderDocumentObject::onChanged(prop);
|
||||
}
|
||||
|
||||
//for feature properties
|
||||
//for feature properties - but each letter/digit in property editor triggers this!
|
||||
void ViewProviderGeomHatch::updateData(const App::Property* prop)
|
||||
{
|
||||
if (prop == &(getViewObject()->ScalePattern)) {
|
||||
updateGraphic();
|
||||
}
|
||||
Gui::ViewProviderDocumentObject::updateData(prop);
|
||||
}
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@ public:
|
||||
virtual void attach(App::DocumentObject *);
|
||||
virtual void updateData(const App::Property*);
|
||||
virtual void onChanged(const App::Property *prop);
|
||||
virtual bool setEdit(int ModNum);
|
||||
virtual void unsetEdit(int ModNum);
|
||||
virtual bool doubleClicked(void);
|
||||
|
||||
virtual bool useNewSelectionModel(void) const {return false;}
|
||||
virtual void setDisplayMode(const char* ModeName);
|
||||
|
||||
Reference in New Issue
Block a user