[TD]allow rotation of hatch directions

- faces can have their svg and bitmap hatches rotated to match
  the view rotation or special situations
- section cut face can have svg hatch rotated
This commit is contained in:
wandererfan
2022-11-30 21:56:09 -05:00
committed by WandererFan
parent cf07ab2dcf
commit 6cc849fb73
17 changed files with 419 additions and 139 deletions

View File

@@ -86,6 +86,10 @@ DrawGeomHatch::DrawGeomHatch()
ADD_PROPERTY_TYPE(ScalePattern, (1.0), vgroup, App::Prop_None,
"GeomHatch pattern size adjustment");
ScalePattern.setConstraints(&scaleRange);
ADD_PROPERTY_TYPE(PatternRotation, (0.0), vgroup, App::Prop_None,
"Pattern rotation in degrees anticlockwise");
ADD_PROPERTY_TYPE(PatternOffset, (0.0, 0.0, 0.0), vgroup, App::Prop_None,
"Pattern offset");
m_saveFile = "";
m_saveName = "";
@@ -242,14 +246,17 @@ std::vector<LineSet> DrawGeomHatch::getTrimmedLines(int i) //get the trimmed
Base::Console().Log("DGH::getTrimmedLines - no source geometry\n");
return result;
}
return getTrimmedLines(source, m_lineSets, i, ScalePattern.getValue());
return getTrimmedLines(source, m_lineSets, i, ScalePattern.getValue(),
PatternRotation.getValue(), PatternOffset.getValue());
}
/* static */
std::vector<LineSet> DrawGeomHatch::getTrimmedLinesSection(DrawViewSection* source,
std::vector<LineSet> lineSets,
TopoDS_Face f,
double scale )
double scale,
double hatchRotation,
Base::Vector3d hatchOffset)
{
std::vector<LineSet> result;
gp_Pln p;
@@ -270,26 +277,35 @@ std::vector<LineSet> DrawGeomHatch::getTrimmedLinesSection(DrawViewSection* sou
result = getTrimmedLines(source,
lineSets,
fMoved,
scale );
scale,
hatchRotation,
hatchOffset );
return result;
}
//! 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> DrawGeomHatch::getTrimmedLines(DrawViewPart* source, std::vector<LineSet> lineSets,
int iface, double scale, double hatchRotation ,
Base::Vector3d hatchOffset)
{
TopoDS_Face face = extractFace(source, iface);
std::vector<LineSet> result = getTrimmedLines(source,
lineSets,
face,
scale );
scale,
hatchRotation,
hatchOffset );
return result;
}
std::vector<LineSet> DrawGeomHatch::getTrimmedLines(DrawViewPart* source,
std::vector<LineSet> lineSets,
TopoDS_Face f,
double scale )
double scale,
double hatchRotation,
Base::Vector3d hatchOffset)
{
// Base::Console().Message("DGH::getTrimmedLines() - rotation: %.3f hatchOffset: %s\n", hatchRotation, DrawUtil::formatVector(hatchOffset).c_str());
(void)source;
std::vector<LineSet> result;
@@ -310,12 +326,26 @@ std::vector<LineSet> DrawGeomHatch::getTrimmedLines(DrawViewPart* source,
//make Compound for this linespec
BRep_Builder builder;
TopoDS_Compound grid;
builder.MakeCompound(grid);
TopoDS_Compound gridComp;
builder.MakeCompound(gridComp);
for (auto& c: candidates) {
builder.Add(grid, c);
builder.Add(gridComp, c);
}
TopoDS_Shape grid = gridComp;
if (hatchRotation != 0.0) {
double hatchRotationRad = hatchRotation * M_PI / 180.0;
gp_Ax1 gridAxis(gp_Pnt(0.0, 0.0, 0.0), gp_Vec(gp::OZ().Direction()));
gp_Trsf xGridRotate;
xGridRotate.SetRotation(gridAxis, hatchRotationRad);
BRepBuilderAPI_Transform mkTransRotate(grid, xGridRotate, true);
grid = mkTransRotate.Shape();
}
gp_Trsf xGridTranslate;
xGridTranslate.SetTranslation(DrawUtil::togp_Vec(hatchOffset));
BRepBuilderAPI_Transform mkTransTranslate(grid, xGridTranslate, true);
grid = mkTransTranslate.Shape();
//Common(Compound, Face)
BRepAlgoAPI_Common mkCommon(face, grid);
if ((!mkCommon.IsDone()) ||
@@ -369,6 +399,15 @@ std::vector<TopoDS_Edge> DrawGeomHatch::makeEdgeOverlay(PATLineSpec hl, Bnd_Box
double minX, maxX, minY, maxY, minZ, maxZ;
b.Get(minX, minY, minZ, maxX, maxY, maxZ);
//make the overlay bigger to cover rotations. might need to be bigger than 2x.
double centerX = (minX + maxX) / 2.0;
double widthX = maxX - minX;
minX = centerX - widthX;
maxX = centerX + widthX;
double centerY = (minY + maxY) / 2.0;
double widthY = maxY - minY;
minY = centerY - widthY;
maxY = centerY + widthY;
Base::Vector3d start;
Base::Vector3d end;

View File

@@ -61,6 +61,8 @@ public:
App::PropertyFileIncluded PatIncluded;
App::PropertyString NamePattern;
App::PropertyFloatConstraint ScalePattern;
App::PropertyFloat PatternRotation;
App::PropertyVector PatternOffset;
App::DocumentObjectExecReturn *execute(void) override;
void onChanged(const App::Property* prop) override;
@@ -77,17 +79,22 @@ public:
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<LineSet> getTrimmedLines(DrawViewPart* dvp, std::vector<LineSet> lineSets, int iface,
double scale, double hatchRotation = 0.0,
Base::Vector3d hatchOffset = Base::Vector3d(0.0, 0.0, 0.0));
static std::vector<LineSet> getTrimmedLines(DrawViewPart* source,
std::vector<LineSet> lineSets,
TopoDS_Face face,
double scale );
double scale , double hatchRotation = 0.0,
Base::Vector3d hatchOffset = Base::Vector3d(0.0, 0.0, 0.0));
static std::vector<LineSet> getTrimmedLinesSection(DrawViewSection* source,
std::vector<LineSet> lineSets,
TopoDS_Face f,
double scale );
double scale , double hatchRotation = 0.0,
Base::Vector3d hatchOffset = Base::Vector3d(0.0, 0.0, 0.0));
static std::vector<TopoDS_Edge> makeEdgeOverlay(PATLineSpec 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<PATLineSpec> getDecodedSpecsFromFile(std::string fileSpec, std::string myPattern);
static TopoDS_Face extractFace(DrawViewPart* source, int iface );

View File

@@ -175,6 +175,8 @@ DrawViewSection::DrawViewSection() :
"Embedded Pat pattern file. System use only."); // n/a to end users
ADD_PROPERTY_TYPE(NameGeomPattern ,(DrawGeomHatch::prefGeomHatchName()), fgroup, App::Prop_None, "The pattern name for geometric hatching");
ADD_PROPERTY_TYPE(HatchScale, (1.0), fgroup, App::Prop_None, "Hatch pattern size adjustment");
ADD_PROPERTY_TYPE(HatchRotation, (0.0), fgroup, App::Prop_None, "Rotation of hatch pattern in degrees anti-clockwise");
ADD_PROPERTY_TYPE(HatchOffset, (0.0, 0.0, 0.0), fgroup, App::Prop_None, "Hatch pattern offset");
getParameters();
@@ -980,7 +982,9 @@ std::vector<LineSet> DrawViewSection::getDrawableLines(int i)
std::vector<LineSet> result;
result = DrawGeomHatch::getTrimmedLinesSection(this, m_lineSets,
getSectionTopoDSFace(i),
HatchScale.getValue());
HatchScale.getValue(),
HatchRotation.getValue(),
HatchOffset.getValue());
return result;
}

View File

@@ -102,6 +102,8 @@ public:
App::PropertyFileIncluded PatIncluded;
App::PropertyString NameGeomPattern;
App::PropertyFloat HatchScale;
App::PropertyFloat HatchRotation;
App::PropertyVector HatchOffset;
App::PropertyBool FuseBeforeCut;
App::PropertyBool TrimAfterCut; //new v021

View File

@@ -68,7 +68,8 @@ using namespace TechDraw;
QGIFace::QGIFace(int index) :
projIndex(index),
m_hideSvgTiles(false)
m_hideSvgTiles(false),
m_hatchRotation(0.0)
{
m_segCount = 0;
// setFillMode(NoFill);
@@ -257,16 +258,17 @@ void QGIFace::lineSetToFillItems(LineSet& ls)
{
m_segCount = 0;
QPen pen = setGeomPen();
for (auto& g: ls.getGeoms()) {
for (auto& geom : ls.getGeoms()) {
//geom is a tdGeometry representation of 1 line in the pattern
if (ls.isDashed()) {
double offset = 0.0;
Base::Vector3d pStart = ls.getPatternStartPoint(g, offset, m_fillScale);
Base::Vector3d pStart = ls.getPatternStartPoint(geom, offset, m_fillScale);
offset = Rez::guiX(offset);
Base::Vector3d gStart(g->getStartPoint().x,
g->getStartPoint().y,
Base::Vector3d gStart(geom->getStartPoint().x,
geom->getStartPoint().y,
0.0);
Base::Vector3d gEnd(g->getEndPoint().x,
g->getEndPoint().y,
Base::Vector3d gEnd(geom->getEndPoint().x,
geom->getEndPoint().y,
0.0);
if (DrawUtil::fpCompare(offset, 0.0, 0.00001)) { //no offset
QGraphicsPathItem* item1 = lineFromPoints(pStart, gEnd, ls.getDashSpec());
@@ -279,12 +281,12 @@ void QGIFace::lineSetToFillItems(LineSet& ls)
}
} else { //offset - pattern start not in g
double remain = dashRemain(decodeDashSpec(ls.getDashSpec()), offset);
QGraphicsPathItem* shortItem = geomToStubbyLine(g, remain, ls);
QGraphicsPathItem* shortItem = geomToStubbyLine(geom, remain, ls);
shortItem->setPen(pen);
m_fillItems.push_back(shortItem);
}
} else { //not dashed
QGraphicsPathItem* fillItem = geomToLine(g, ls);
QGraphicsPathItem* fillItem = geomToLine(geom, ls);
fillItem->setPen(pen);
m_fillItems.push_back(fillItem);
}
@@ -520,19 +522,20 @@ void QGIFace::makeMark(double x, double y)
void QGIFace::buildSvgHatch()
{
// Base::Console().Message("QGIF::buildSvgHatch() - offset: %s\n", DrawUtil::formatVector(getHatchOffset()).c_str());
double wTile = SVGSIZEW * m_fillScale;
double hTile = SVGSIZEH * m_fillScale;
double w = m_outline.boundingRect().width();
double h = m_outline.boundingRect().height();
QRectF r = m_outline.boundingRect();
QPointF fCenter = r.center();
double nw = ceil(w / wTile);
double nh = ceil(h / hTile);
//make the hatch tiled area big enough to handle rotations
double hatchOverlaySize = 2.0 * std::max(w, h);
QPointF faceCenter = m_outline.boundingRect().center();
double nw = ceil(hatchOverlaySize / wTile);
double nh = ceil(hatchOverlaySize / hTile);
w = nw * wTile;
h = nh * hTile;
m_rect->setRect(0., 0., w,-h);
m_rect->centerAt(fCenter);
r = m_rect->rect();
m_rect->centerAt(faceCenter);
QByteArray before, after;
before = QString::fromStdString(SVGCOLPREFIX + SVGCOLDEFAULT).toUtf8();
after = QString::fromStdString(SVGCOLPREFIX + m_svgCol).toUtf8();
@@ -544,7 +547,8 @@ void QGIFace::buildSvgHatch()
tile->setScale(m_fillScale);
if (tile->load(&colorXML)) {
tile->setParentItem(m_rect);
tile->setPos(iw*wTile, -h + ih*hTile);
tile->setPos(iw*wTile + getHatchOffset().x,
-h + ih*hTile + getHatchOffset().y);
}
tileCount++;
if (tileCount > m_maxTile) {
@@ -556,6 +560,9 @@ void QGIFace::buildSvgHatch()
break;
}
}
QPointF faceCenterToMRect = mapToItem(m_rect, faceCenter);
m_rect->setTransformOriginPoint(faceCenterToMRect);
m_rect->setRotation(m_hatchRotation);
}
void QGIFace::clearSvg()
@@ -565,21 +572,22 @@ void QGIFace::clearSvg()
void QGIFace::buildPixHatch()
{
// Base::Console().Message("QGIF::buildPixHatch() - offset: %s\n", DrawUtil::formatVector(getHatchOffset()).c_str());
double wTile = SVGSIZEW * m_fillScale;
double hTile = SVGSIZEH * m_fillScale;
double w = m_outline.boundingRect().width();
double h = m_outline.boundingRect().height();
QRectF r = m_outline.boundingRect();
QPointF fCenter = r.center();
double nw = ceil(w / wTile);
double nh = ceil(h / hTile);
w = nw * wTile;
h = nh * hTile;
double faceWidth = m_outline.boundingRect().width();
double faceHeight = m_outline.boundingRect().height();
QRectF faceRect = m_outline.boundingRect();
QPointF faceCenter = faceRect.center();
double hatchOverlaySize = 2.0 * std::max(faceWidth, faceHeight);
double numberWide = ceil(hatchOverlaySize / wTile);
double numberHigh = ceil(hatchOverlaySize / hTile);
double overlayWidth = numberWide * wTile;
double overlayHeight= numberHigh * hTile;
m_rect->setRect(0., 0., w,-h);
m_rect->centerAt(fCenter);
m_rect->setRect(0., 0., overlayWidth, -overlayHeight);
m_rect->centerAt(faceCenter);
r = m_rect->rect();
QByteArray before, after;
before = QString::fromStdString(SVGCOLPREFIX + SVGCOLDEFAULT).toUtf8();
after = QString::fromStdString(SVGCOLPREFIX + m_svgCol).toUtf8();
@@ -590,16 +598,16 @@ void QGIFace::buildPixHatch()
Base::Console().Error("QGIF::buildPixHatch - renderer failed to load\n");
}
//get the svg tile graphics as a QImage
QImage imageIn(64, 64, QImage::Format_ARGB32);
imageIn.fill(Qt::transparent);
QPainter painter(&imageIn);
renderer.render(&painter);
if (imageIn.isNull()) {
Base::Console().Error("QGIF::buildPixHatch - imageIn is null\n");
return;
}
//make a QPixmap tile of the QImage
QPixmap pm(64, 64);
pm = QPixmap::fromImage(imageIn);
pm = pm.scaled(wTile, hTile);
@@ -608,23 +616,26 @@ void QGIFace::buildPixHatch()
return;
}
QImage tileField(w, h, QImage::Format_ARGB32);
QPointF fieldCenter(w / 2.0, h / 2.0);
//layout a field of QPixmap tiles as a QImage
QImage tileField(overlayWidth, overlayHeight, QImage::Format_ARGB32);
QPointF fieldCenter(overlayWidth, overlayHeight);
//do we have to rotate the field before we clip it??
tileField.fill(Qt::transparent);
QPainter painter2(&tileField);
QPainter::RenderHints hints = painter2.renderHints();
hints = hints & QPainter::Antialiasing;
painter2.setRenderHints(hints);
QPainterPath clipper = path();
QPointF offset = (fieldCenter - fCenter);
QPointF offset = (fieldCenter - faceCenter);
clipper.translate(offset);
painter2.setClipPath(clipper);
long int tileCount = 0;
for (int iw = 0; iw < int(nw); iw++) {
for (int ih = 0; ih < int(nh); ih++) {
painter2.drawPixmap(QRectF(iw*wTile, ih*hTile, wTile, hTile), //target rect
for (int iw = 0; iw < int(numberWide); iw++) {
for (int ih = 0; ih < int(numberHigh); ih++) {
painter2.drawPixmap(QRectF(iw*wTile + getHatchOffset().x, ih*hTile + getHatchOffset().y,
wTile, hTile), //target rect
pm, //map
QRectF(0, 0, wTile, hTile)); //source rect
tileCount++;
@@ -637,13 +648,14 @@ void QGIFace::buildPixHatch()
break;
}
}
QPixmap bigMap(fabs(r.width()), fabs(r.height()));
QPixmap bigMap(fabs(faceRect.width()), fabs(faceRect.height()));
bigMap = QPixmap::fromImage(tileField);
QPixmap nothing;
m_image->setPixmap(nothing);
m_image->load(bigMap);
m_image->centerAt(fCenter);
m_image->centerAt(faceCenter);
}
//this isn't used currently
@@ -692,6 +704,11 @@ QPixmap QGIFace::textureFromBitmap(std::string fileSpec)
}
QByteArray bytes = f.readAll();
pix.loadFromData(bytes);
if (m_hatchRotation != 0.0) {
QTransform rotator;
rotator.rotate(m_hatchRotation);
pix = pix.transformed(rotator);
}
return pix;
}

View File

@@ -113,6 +113,13 @@ public:
QPixmap textureFromBitmap(std::string fileSpec);
QPixmap textureFromSvg(std::string fillSpec);
//Qt uses clockwise degrees
void setHatchRotation(double degrees) { m_hatchRotation = -degrees; }
double getHatchRotation() const { return -m_hatchRotation; }
void setHatchOffset(Base::Vector3d offset) { m_hatchOffset = offset; }
Base::Vector3d getHatchOffset() { return m_hatchOffset; }
protected:
void makeMark(double x, double y);
double getXForm();
@@ -146,7 +153,6 @@ protected:
bool m_hideSvgTiles;
private:
QPixmap m_texture; //
@@ -158,6 +164,10 @@ private:
double m_geomWeight; //lineweight for crosshatch lines
bool m_defClearFace;
QColor m_defFaceColor;
double m_hatchRotation;
Base::Vector3d m_hatchOffset;
};
}

View File

@@ -485,6 +485,8 @@ void QGIViewPart::drawViewPart()
if (hatchScale > 0.0) {
newFace->setHatchScale(fGeom->ScalePattern.getValue());
}
newFace->setHatchRotation(fGeom->PatternRotation.getValue());
newFace->setHatchOffset(fGeom->PatternOffset.getValue());
newFace->setHatchFile(fGeom->PatIncluded.getValue());
Gui::ViewProvider* gvp = QGIView::getViewProvider(fGeom);
ViewProviderGeomHatch* geomVp = dynamic_cast<ViewProviderGeomHatch*>(gvp);
@@ -495,6 +497,8 @@ void QGIViewPart::drawViewPart()
}
}
} else if (fHatch) {
Gui::ViewProvider* gvp = QGIView::getViewProvider(fHatch);
ViewProviderHatch* hatchVp = dynamic_cast<ViewProviderHatch*>(gvp);
if (fHatch->isSvgHatch()) {
if (!fHatch->SvgIncluded.isEmpty()) {
if (getExporting()) {
@@ -505,20 +509,25 @@ void QGIViewPart::drawViewPart()
newFace->isHatched(true);
newFace->setFillMode(QGIFace::SvgFill);
newFace->setHatchFile(fHatch->SvgIncluded.getValue());
Gui::ViewProvider* gvp = QGIView::getViewProvider(fHatch);
ViewProviderHatch* hatchVp = dynamic_cast<ViewProviderHatch*>(gvp);
// Gui::ViewProvider* gvp = QGIView::getViewProvider(fHatch);
// ViewProviderHatch* hatchVp = dynamic_cast<ViewProviderHatch*>(gvp);
if (hatchVp) {
double hatchScale = hatchVp->HatchScale.getValue();
if (hatchScale > 0.0) {
newFace->setHatchScale(hatchVp->HatchScale.getValue());
}
newFace->setHatchColor(hatchVp->HatchColor.getValue());
newFace->setHatchRotation(hatchVp->HatchRotation.getValue());
newFace->setHatchOffset(hatchVp->HatchOffset.getValue());
}
}
} else { //bitmap hatch
newFace->isHatched(true);
newFace->setFillMode(QGIFace::BitmapFill);
newFace->setHatchFile(fHatch->SvgIncluded.getValue());
if (hatchVp) {
newFace->setHatchRotation(hatchVp->HatchRotation.getValue());
}
}
}
bool drawEdges = prefFaceEdges();

View File

@@ -117,7 +117,8 @@ void QGIViewSection::drawSectionFace()
newFace->setFillMode(QGIFace::SvgFill);
newFace->setHatchColor(sectionVp->HatchColor.getValue());
newFace->setHatchScale(section->HatchScale.getValue());
// std::string hatchSpec = section->FileHatchPattern.getValue();
newFace->setHatchRotation(section->HatchRotation.getValue());
newFace->setHatchOffset(section->HatchOffset.getValue());
std::string hatchSpec = section->SvgIncluded.getValue();
newFace->setHatchFile(hatchSpec);
} else if (section->CutSurfaceDisplay.isValue("PatHatch")) {
@@ -126,6 +127,8 @@ void QGIViewSection::drawSectionFace()
newFace->setHatchColor(sectionVp->GeomHatchColor.getValue());
newFace->setHatchScale(section->HatchScale.getValue());
newFace->setLineWeight(sectionVp->WeightPattern.getValue());
newFace->setHatchRotation(section->HatchRotation.getValue());
newFace->setHatchOffset(section->HatchOffset.getValue());
std::vector<TechDraw::LineSet> lineSets = section->getDrawableLines(i);
if (!lineSets.empty()) {
newFace->clearLineSets();

View File

@@ -90,6 +90,13 @@ void TaskGeomHatch::initUi()
connect(ui->sbWeight, SIGNAL(valueChanged(double)), this, SLOT(onLineWeightChanged()));
ui->ccColor->setColor(m_color.asValue<QColor>());
connect(ui->ccColor, SIGNAL(changed()), this, SLOT(onColorChanged()));
ui->dsbRotation->setValue(m_rotation);
connect(ui->dsbRotation, SIGNAL(valueChanged(double)), this, SLOT(onRotationChanged()));
ui->dsbOffsetX->setValue(m_offset.x);
connect(ui->dsbOffsetX, SIGNAL(valueChanged(double)), this, SLOT(onOffsetChanged()));
ui->dsbOffsetY->setValue(m_offset.y);
connect(ui->dsbOffsetY, SIGNAL(valueChanged(double)), this, SLOT(onOffsetChanged()));
}
void TaskGeomHatch::onFileChanged()
@@ -119,6 +126,23 @@ void TaskGeomHatch::onScaleChanged()
dv->requestPaint();
}
void TaskGeomHatch::onRotationChanged()
{
m_rotation = ui->dsbRotation->value();
m_hatch->PatternRotation.setValue(m_rotation);
TechDraw::DrawView* dv = static_cast<TechDraw::DrawView*>(m_source);
dv->requestPaint();
}
void TaskGeomHatch::onOffsetChanged()
{
Base::Vector3d offset(ui->dsbOffsetX->value(), ui->dsbOffsetY->value(), 0.0);
m_offset = offset;
m_hatch->PatternOffset.setValue(m_offset);
TechDraw::DrawView* dv = static_cast<TechDraw::DrawView*>(m_source);
dv->requestPaint();
}
void TaskGeomHatch::onLineWeightChanged()
{
m_weight =ui->sbWeight->value().getValue();
@@ -156,6 +180,8 @@ bool TaskGeomHatch::reject()
m_hatch->FilePattern.setValue(m_origFile);
m_hatch->NamePattern.setValue(m_origName);
m_hatch->ScalePattern.setValue(m_origScale);
m_hatch->PatternRotation.setValue(m_origRotation);
m_hatch->PatternOffset.setValue(m_origOffset);
m_Vp->ColorPattern.setValue(m_origColor);
m_Vp->WeightPattern.setValue(m_origWeight);
}
@@ -167,6 +193,8 @@ void TaskGeomHatch::getParameters()
m_file = m_hatch->FilePattern.getValue();
m_name = m_hatch->NamePattern.getValue();
m_scale = m_hatch->ScalePattern.getValue();
m_rotation = m_hatch->PatternRotation.getValue();
m_offset = m_hatch->PatternOffset.getValue();
m_color = m_Vp->ColorPattern.getValue();
m_weight = m_Vp->WeightPattern.getValue();
if (!getCreateMode()) {
@@ -175,6 +203,8 @@ void TaskGeomHatch::getParameters()
m_origScale = m_hatch->ScalePattern.getValue();
m_origColor = m_Vp->ColorPattern.getValue();
m_origWeight = m_Vp->WeightPattern.getValue();
m_origRotation = m_hatch->PatternRotation.getValue();
m_origOffset = m_hatch->PatternOffset.getValue();
}
}
@@ -193,6 +223,7 @@ void TaskGeomHatch::updateValues()
m_Vp->ColorPattern.setValue(m_color);
m_weight = ui->sbWeight->value().getValue();
m_Vp->WeightPattern.setValue(m_weight);
m_hatch->PatternRotation.setValue(ui->dsbRotation->value());
}
QStringList TaskGeomHatch::listToQ(std::vector<std::string> inList)

View File

@@ -83,6 +83,10 @@ private:
double m_origScale;
double m_origWeight;
App::Color m_origColor;
double m_rotation;
double m_origRotation;
Base::Vector3d m_offset;
Base::Vector3d m_origOffset;
bool m_createMode;
@@ -91,6 +95,8 @@ private Q_SLOTS:
void onScaleChanged();
void onLineWeightChanged();
void onColorChanged();
void onRotationChanged();
void onOffsetChanged();
};

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>385</width>
<height>191</height>
<height>314</height>
</rect>
</property>
<property name="sizePolicy">
@@ -47,7 +47,7 @@
</property>
</widget>
</item>
<item row="0" column="1">
<item row="0" column="1">
<widget class="Gui::FileChooser" name="fcFile">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
@@ -60,10 +60,37 @@
</property>
</widget>
</item>
</layout>
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_2" columnstretch="1,0,1">
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Pattern Scale</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Rotation</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="Gui::ColorButton" name="ccColor">
<property name="minimumSize">
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="toolTip">
<string>Color of pattern lines</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
@@ -71,18 +98,12 @@
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
<item row="5" column="0">
<widget class="QLabel" name="label_7">
<property name="text">
<string>Offset X</string>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="cbName">
@@ -97,41 +118,6 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Pattern Scale</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="Gui::QuantitySpinBox" name="sbScale">
<property name="minimumSize">
<size>
<width>0</width>
<height>22</height>
</size>
</property>
<property name="toolTip">
<string>Enlarges/shrinks the pattern</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
@@ -139,6 +125,22 @@
</property>
</widget>
</item>
<item row="4" column="2">
<widget class="QDoubleSpinBox" name="dsbRotation">
<property name="wrapping">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="Gui::QuantitySpinBox" name="sbWeight">
<property name="minimumSize">
@@ -167,15 +169,28 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="0" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Line Color</string>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="Gui::ColorButton" name="ccColor">
<item row="1" column="2">
<widget class="Gui::QuantitySpinBox" name="sbScale">
<property name="minimumSize">
<size>
<width>0</width>
@@ -183,11 +198,47 @@
</size>
</property>
<property name="toolTip">
<string>Color of pattern lines</string>
<string>Enlarges/shrinks the pattern</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="keyboardTracking">
<bool>false</bool>
</property>
<property name="minimum">
<double>0.100000000000000</double>
</property>
<property name="singleStep">
<double>0.100000000000000</double>
</property>
<property name="value">
<double>1.000000000000000</double>
</property>
</widget>
</item>
</layout>
<item row="6" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Offset Y</string>
</property>
</widget>
</item>
<item row="5" column="2">
<widget class="QDoubleSpinBox" name="dsbOffsetX">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QDoubleSpinBox" name="dsbOffsetY">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>

View File

@@ -68,7 +68,9 @@ TaskHatch::TaskHatch(TechDraw::DrawViewPart* inDvp, std::vector<std::string> sub
connect(ui->fcFile, SIGNAL(fileNameSelected(QString)), this, SLOT(onFileChanged()));
connect(ui->sbScale, SIGNAL(valueChanged(double)), this, SLOT(onScaleChanged()));
connect(ui->ccColor, SIGNAL(changed()), this, SLOT(onColorChanged()));
connect(ui->dsbRotation, SIGNAL(valueChanged(double)), this, SLOT(onRotationChanged()));
connect(ui->dsbOffsetX, SIGNAL(valueChanged(double)), this, SLOT(onOffsetChanged()));
connect(ui->dsbOffsetY, SIGNAL(valueChanged(double)), this, SLOT(onOffsetChanged()));
setUiPrimary();
}
@@ -86,6 +88,9 @@ TaskHatch::TaskHatch(TechDrawGui::ViewProviderHatch* inVp) :
connect(ui->fcFile, SIGNAL(fileNameSelected(QString)), this, SLOT(onFileChanged()));
connect(ui->sbScale, SIGNAL(valueChanged(double)), this, SLOT(onScaleChanged()));
connect(ui->ccColor, SIGNAL(changed()), this, SLOT(onColorChanged()));
connect(ui->dsbRotation, SIGNAL(valueChanged(double)), this, SLOT(onRotationChanged()));
connect(ui->dsbOffsetX, SIGNAL(valueChanged(double)), this, SLOT(onOffsetChanged()));
connect(ui->dsbOffsetY, SIGNAL(valueChanged(double)), this, SLOT(onOffsetChanged()));
saveHatchState();
setUiEdit();
@@ -103,6 +108,7 @@ void TaskHatch::setUiPrimary()
ui->sbScale->setValue(1.0);
ui->sbScale->setSingleStep(0.1);
ui->ccColor->setColor(TechDraw::DrawHatch::prefSvgHatchColor().asValue<QColor>());
ui->dsbRotation->setValue(0.0);
}
void TaskHatch::setUiEdit()
@@ -114,6 +120,9 @@ void TaskHatch::setUiEdit()
ui->sbScale->setValue(m_saveScale);
ui->sbScale->setSingleStep(0.1);
ui->ccColor->setColor(m_saveColor.asValue<QColor>());
ui->dsbRotation->setValue(m_saveRotation);
ui->dsbOffsetX->setValue(m_saveOffset.x);
ui->dsbOffsetY->setValue(m_saveOffset.y);
}
void TaskHatch::saveHatchState()
@@ -121,6 +130,9 @@ void TaskHatch::saveHatchState()
m_saveFile = m_hatch->HatchPattern.getValue();
m_saveScale = m_vp->HatchScale.getValue();
m_saveColor = m_vp->HatchColor.getValue();
m_saveRotation = m_vp->HatchRotation.getValue();
m_saveOffset = m_vp->HatchOffset.getValue();
}
//restore the start conditions
@@ -131,6 +143,8 @@ void TaskHatch::restoreHatchState()
m_hatch->HatchPattern.setValue(m_saveFile);
m_vp->HatchScale.setValue(m_saveScale);
m_vp->HatchColor.setValue(m_saveColor);
m_vp->HatchRotation.setValue(m_saveRotation);
m_vp->HatchOffset.setValue(m_saveOffset);
}
}
@@ -152,6 +166,19 @@ void TaskHatch::onColorChanged()
apply();
}
void TaskHatch::onRotationChanged()
{
m_rotation = ui->dsbRotation->value();
apply();
}
void TaskHatch::onOffsetChanged()
{
m_offset.x = ui->dsbOffsetX->value();
m_offset.y = ui->dsbOffsetY->value();
apply();
}
void TaskHatch::apply(bool forceUpdate)
{
Q_UNUSED(forceUpdate)
@@ -173,7 +200,7 @@ void TaskHatch::apply(bool forceUpdate)
void TaskHatch::createHatch()
{
Base::Console().Message("TH::createHatch()\n");
// Base::Console().Message("TH::createHatch()\n");
App::Document* doc = m_dvp->getDocument();
std::string FeatName = doc->getUniqueObjectName("Hatch");
std::stringstream featLabel;
@@ -200,6 +227,9 @@ void TaskHatch::createHatch()
ac.setValue<QColor>(ui->ccColor->color());
m_vp->HatchColor.setValue(ac);
m_vp->HatchScale.setValue(ui->sbScale->value().getValue());
m_vp->HatchRotation.setValue(ui->dsbRotation->value());
Base::Vector3d offset(ui->dsbOffsetX->value(), ui->dsbOffsetY->value(), 0.0);
m_vp->HatchOffset.setValue(offset);
} else {
Base::Console().Error("TaskHatch - Hatch has no ViewProvider\n");
}
@@ -221,6 +251,9 @@ void TaskHatch::updateHatch()
ac.setValue<QColor>(ui->ccColor->color());
m_vp->HatchColor.setValue(ac);
m_vp->HatchScale.setValue(ui->sbScale->value().getValue());
m_vp->HatchRotation.setValue(ui->dsbRotation->value());
Base::Vector3d offset(ui->dsbOffsetX->value(), ui->dsbOffsetY->value(), 0.0);
m_vp->HatchOffset.setValue(offset);
Command::commitCommand();
}

View File

@@ -61,6 +61,8 @@ protected Q_SLOTS:
void onFileChanged();
void onScaleChanged();
void onColorChanged();
void onRotationChanged();
void onOffsetChanged();
protected:
void changeEvent(QEvent *e) override;
@@ -85,11 +87,15 @@ private:
std::string m_file;
double m_scale;
App::Color m_color;
double m_rotation;
Base::Vector3d m_offset;
std::string m_saveFile;
double m_saveScale;
App::Color m_saveColor;
std::vector<std::string> m_saveSubs;
double m_saveRotation;
Base::Vector3d m_saveOffset;
};

View File

@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>398</width>
<height>148</height>
<height>244</height>
</rect>
</property>
<property name="sizePolicy">
@@ -66,26 +66,7 @@
</layout>
</item>
<item>
<layout class="QGridLayout" name="gridLayout_3" rowstretch="0,0,0" columnstretch="0,0">
<item row="2" column="1">
<widget class="Gui::ColorButton" name="ccColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="toolTip">
<string>Color of pattern lines (Svg Only)</string>
</property>
</widget>
</item>
<layout class="QGridLayout" name="gridLayout_3" rowstretch="0,0,0,0,0,0" columnstretch="0,0">
<item row="1" column="1">
<widget class="Gui::QuantitySpinBox" name="sbScale">
<property name="sizePolicy">
@@ -120,6 +101,58 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Svg Line Color</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Offset X</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::ColorButton" name="ccColor">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<property name="toolTip">
<string>Color of pattern lines (Svg Only)</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QDoubleSpinBox" name="dsbRotation">
<property name="toolTip">
<string>Rotation the pattern (degrees)</string>
</property>
<property name="wrapping">
<bool>true</bool>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
@@ -127,10 +160,31 @@
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Svg Line Color</string>
<string>Rotation</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>Offset Y</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QDoubleSpinBox" name="dsbOffsetX">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QDoubleSpinBox" name="dsbOffsetY">
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>

View File

@@ -65,6 +65,8 @@ ViewProviderHatch::ViewProviderHatch()
vgroup, App::Prop_None, "The color of the hatch pattern");
ADD_PROPERTY_TYPE(HatchScale, (1.0), vgroup, App::Prop_None, "Hatch pattern size adjustment");
HatchScale.setConstraints(&scaleRange);
ADD_PROPERTY_TYPE(HatchRotation, (0.0), vgroup, App::Prop_None, "Hatch pattern rotation");
ADD_PROPERTY_TYPE(HatchOffset, (0.0, 0.0, 0.0), vgroup, App::Prop_None, "Hatch pattern offset");
}
ViewProviderHatch::~ViewProviderHatch()
@@ -94,8 +96,10 @@ bool ViewProviderHatch::doubleClicked()
void ViewProviderHatch::onChanged(const App::Property* prop)
{
if ((prop == &HatchScale) ||
(prop == &HatchColor)) {
if (prop == &HatchScale ||
prop == &HatchColor ||
prop == &HatchRotation ||
prop == &HatchOffset) {
if (HatchScale.getValue() > 0.0) {
TechDraw::DrawViewPart* parent = getViewObject()->getSourceView();
if (parent) {

View File

@@ -26,6 +26,7 @@
#define DRAWINGGUI_VIEWPROVIDERHATCH_H
#include <Mod/TechDraw/TechDrawGlobal.h>
#include <App/PropertyGeo.h>
#include <Gui/ViewProviderDocumentObject.h>
@@ -46,8 +47,10 @@ public:
/// destructor
~ViewProviderHatch() override;
App::PropertyColor HatchColor;
App::PropertyColor HatchColor;
App::PropertyFloatConstraint HatchScale;
App::PropertyFloat HatchRotation;
App::PropertyVector HatchOffset;
bool useNewSelectionModel() const override {return false;}
void onChanged(const App::Property* prop) override;

View File

@@ -99,7 +99,8 @@ void ViewProviderViewSection::updateData(const App::Property* prop)
if (prop == &(getViewObject()->FileHatchPattern) ||
prop == &(getViewObject()->CutSurfaceDisplay) ||
prop == &(getViewObject()->NameGeomPattern) ||
prop == &(getViewObject()->HatchScale) ) {
prop == &(getViewObject()->HatchScale) ||
prop == &(getViewObject()->HatchRotation) ) {
updateGraphic();
}