/** * Draw a DimRadial * TODO: 1) Draw correct leader * 2) Change text position such that it's correctly placed under the text. I am not 100% sure how this is done from DXF * It could be that Attachmentpoint is simply incorrect?!?!?! or that the DXF importer is incorrect? * */ void LCDimRadial::draw(LcPainter& painter, const LcDrawOptions &options, const lc::geo::Area& rect) const { bool modified = false; // Decide to show the explecit value or the measured value double radiusCircle = this->definitionPoint().distanceTo(this->definitionPoint2()); const lc::geo::Coordinate& mousePos = middleOfText(); const bool mouseIsInside = mousePos.distanceTo(definitionPoint()) < radiusCircle; // FIXME this should not be fixed const double capSize = 2.; std::string value = lc::StringHelper::dim_value(explicitValue(), options.radialFormat(), radiusCircle); /* get text size */ painter.save(); painter.font_size(options.dimTextHeight()); TextExtends te = painter.text_extends(value.c_str()); painter.restore(); // Draw line EndCaps endCaps; auto tLinePos = !mouseIsInside ? mousePos.move(mousePos - lc::geo::Coordinate(definitionPoint().x(), mousePos.y()), te.width + capSize) : mousePos.move(mousePos - lc::geo::Coordinate(definitionPoint().x(), mousePos.y()), -te.width - capSize); auto tMText = !mouseIsInside ? mousePos.move(mousePos - lc::geo::Coordinate(definitionPoint().x(), mousePos.y()), te.width / 2 + capSize / 2) : mousePos.move(mousePos - lc::geo::Coordinate(definitionPoint().x(), mousePos.y()), -te.width / 2 - capSize / 2); painter.move_to(definitionPoint2().x(), definitionPoint2().y()); painter.line_to(mousePos.x(), mousePos.y()); painter.line_to(tLinePos.x(), mousePos.y()); painter.stroke(); endCaps.render(painter, EndCaps::CLOSEDARROW, mousePos.x(), mousePos.y(), definitionPoint2().x(), definitionPoint2().y(), capSize) ; this->drawText(value, textAngle(), lc::TextConst::AttachmentPoint::Top_center, tMText, painter, options, rect); if (modified) { painter.restore(); } }
/** * Draw a DimDiametric * TODO: draw correct leader and verification if we draw this correctly compared to other CAD drawings */ void LCDimDiametric::draw(LcPainter &painter, const LcDrawOptions &options, const lc::geo::Area &rect) const { // Decide to show the explecit value or the measured value auto diameterCircle = _dimDiametric->definitionPoint().distanceTo(_dimDiametric->definitionPoint2()); auto circle_middle_p0 = _dimDiametric->definitionPoint2().mid(_dimDiametric->definitionPoint()); // FIXME this should not be fixed const double capSize = 2.; auto value = lc::tools::StringHelper::dim_value( _dimDiametric->explicitValue(), options.diametricFormat(), diameterCircle ); /* get text size */ painter.save(); painter.font_size(options.dimTextHeight(), false); TextExtends te = painter.text_extends(value.c_str()); painter.restore(); EndCaps endCaps; const bool textisInside = _dimDiametric->middleOfText().distanceTo(circle_middle_p0) < diameterCircle / 2.; const bool textFitsInside = diameterCircle > te.width; // Draw inside if the text really fit's and if it was initially setup inside // No sure if this follow's DXF spec?? if (textisInside && textFitsInside) { painter.move_to(_dimDiametric->definitionPoint().x(), _dimDiametric->definitionPoint().y()); painter.line_to(_dimDiametric->definitionPoint2().x(), _dimDiametric->definitionPoint2().y()); painter.stroke(); endCaps.render( painter, EndCaps::CLOSEDARROW, _dimDiametric->definitionPoint().x(), _dimDiametric->definitionPoint().y(), _dimDiametric->definitionPoint2().x(), _dimDiametric->definitionPoint2().y(), capSize ); endCaps.render( painter, EndCaps::CLOSEDARROW, _dimDiametric->definitionPoint2().x(), _dimDiametric->definitionPoint2().y(), _dimDiametric->definitionPoint().x(), _dimDiametric->definitionPoint().y(), capSize ); this->drawText( value, _dimDiametric->textAngle(), lc::TextConst::AttachmentPoint::Top_center, _dimDiametric->middleOfText(), painter, options, rect ); } else { // When we draw text outside, we move the arrows around (facing inwards) and we draw a small leader where we place the text on // here we ignore _dimDiametric->middleOfText() and I am not sure if that's suppose to work like that (RVT) auto center = _dimDiametric->definitionPoint().mid(_dimDiametric->definitionPoint2()); auto p1 = _dimDiametric->definitionPoint().moveTo(center, -capSize * 1.5); auto p2 = _dimDiametric->definitionPoint2().moveTo(center, -capSize * 1.5); // take largest X value of both _dimDiametric->definition points (on the right) and draw text there if (p1.x() > p2.x()) { painter.move_to(p1.x() + capSize, p1.y()); painter.line_to(p1.x(), p1.y()); painter.line_to(p2.x(), p2.y()); painter.stroke(); this->drawText( value, _dimDiametric->textAngle(), lc::TextConst::AttachmentPoint::Top_left, lc::geo::Coordinate(p1.x(), p1.y()), painter, options, rect ); } else { painter.move_to(p2.x() + capSize, p2.y()); painter.line_to(p2.x(), p2.y()); painter.line_to(p1.x(), p1.y()); painter.stroke(); this->drawText( value, _dimDiametric->textAngle(), lc::TextConst::AttachmentPoint::Top_right, lc::geo::Coordinate(p2.x(), p2.y()), painter, options, rect ); } endCaps.render( painter, EndCaps::CLOSEDARROW, p1.x(), p1.y(), _dimDiametric->definitionPoint().x(), _dimDiametric->definitionPoint().y(), capSize ); endCaps.render( painter, EndCaps::CLOSEDARROW, p2.x(), p2.y(), _dimDiametric->definitionPoint2().x(), _dimDiametric->definitionPoint2().y(), capSize ); } }