Permalink
Browse files

Fix arc/lwpolyline rendering

  • Loading branch information...
feragon committed Aug 5, 2017
1 parent 6049e12 commit 3f691b700455bb916463777aea273a1213c5cea7
@@ -68,7 +68,7 @@ bool Intersect::operator()(const lc::geo::Vector &v, const lc::entity::Spline &s
}
bool Intersect::operator()(const lc::geo::Vector &v, const lc::entity::LWPolyline &l) {
auto list1 = l.asGeometrics();
auto list1 = l.asEntities();
// Note: The dynamic_pointer_cast won't winn a beauty contest, but the plan is to split
// the EntityVisitor into a GeoVisitor and EntityVisitor such that a applicaiton deciding
@@ -129,7 +129,7 @@ bool Intersect::operator()(const lc::entity::Line &, const lc::entity::Spline &)
}
bool Intersect::operator()(const lc::entity::Line &l, const lc::entity::LWPolyline &p) {
auto &&list1 = p.asGeometrics();
auto &&list1 = p.asEntities();
// Note: The dynamic_pointer_cast won't winn a beauty contest, but the plan is to split
// the EntityVisitor into a GeoVisitor and EntityVisitor such that a applicaiton deciding
// to use double dispatch can decide to use a specific implementation.
@@ -245,7 +245,7 @@ bool Intersect::operator()(const lc::entity::Circle &c, const lc::entity::Spline
}
bool Intersect::operator()(const lc::entity::Circle &c, const lc::entity::LWPolyline &l) {
auto &list1 = l.asGeometrics();
auto &list1 = l.asEntities();
auto a = lc::geo::Arc(c.center(), c.radius(), -M_PI, M_PI);
// Note: The dynamic_pointer_cast won't winn a beauty contest, but the plan is to split
// the EntityVisitor into a GeoVisitor and EntityVisitor such that a applicaiton deciding
@@ -348,7 +348,7 @@ bool Intersect::operator()(const lc::entity::Arc &a, const lc::entity::Spline &s
}
bool Intersect::operator()(const lc::entity::Arc &a1, const lc::entity::LWPolyline &l1) {
auto &list1 = l1.asGeometrics();
auto &list1 = l1.asEntities();
// Note: The dynamic_pointer_cast won't winn a beauty contest, but the plan is to split
// the EntityVisitor into a GeoVisitor and EntityVisitor such that a applicaiton deciding
// to use double dispatch can decide to use a specific implementation.
@@ -490,8 +490,8 @@ bool Intersect::operator()(const lc::entity::LWPolyline &p, const lc::entity::Sp
}
bool Intersect::operator()(const lc::entity::LWPolyline &l1, const lc::entity::LWPolyline &l2) {
auto &list1 = l1.asGeometrics();
auto &list2 = l2.asGeometrics();
auto &list1 = l1.asEntities();
auto &list2 = l2.asEntities();
// Note: The dynamic_pointer_cast won't winn a beauty contest, but the plan is to split
// the EntityVisitor into a GeoVisitor and EntityVisitor such that a applicaiton deciding
@@ -49,7 +49,7 @@ Arc Arc::createArc3P(const Coordinate &p1, const Coordinate &p2, const Coordinat
}
Arc Arc::createArcBulge(const Coordinate &p1, const Coordinate &p2, const double bulge) {
auto isCCW = bulge<0.;
auto isCCW = bulge>0.;
auto alpha = atan(bulge)*4.;
auto middle = p1.mid(p2);
@@ -179,7 +179,9 @@ double Arc::angle() const {
double Arc::bulge() const {
double bulge = std::tan(angle()/4.0);
if(CCW()) bulge *= -1;
if(!CCW()) {
bulge *= -1;
}
return bulge;
}
@@ -9,8 +9,8 @@ Arc::Arc(const geo::Coordinate &center, double radius, double startAngle, double
geo::Arc(center, radius, startAngle, endAngle, isCCW) {
}
Arc::Arc(const geo::Arc &a, const Layer_CSPtr layer, const MetaInfo_CSPtr metaInfo) :
CADEntity(layer, metaInfo),
Arc::Arc(const geo::Arc &a, const Layer_CSPtr layer, const MetaInfo_CSPtr metaInfo, const Block_CSPtr block) :
CADEntity(layer, metaInfo, block),
geo::Arc(a) {
}
@@ -35,7 +35,7 @@ namespace lc {
const Block_CSPtr block = nullptr
);
Arc(const geo::Arc &a, const Layer_CSPtr layer, const MetaInfo_CSPtr metaInfo);
Arc(const geo::Arc &a, const Layer_CSPtr layer, const MetaInfo_CSPtr metaInfo, const Block_CSPtr block = nullptr);
Arc(const Arc_CSPtr other, bool sameID = false);
@@ -5,6 +5,8 @@
#include <cad/vo/entitycoordinate.h>
#include <cad/interface/snapconstrain.h>
#include <cad/interface/snapable.h>
#include <cad/primitive/arc.h>
#include <cad/primitive/line.h>
using namespace lc;
using namespace entity;
@@ -26,6 +28,9 @@ LWPolyline::LWPolyline(const std::vector<LWVertex2D> &vertex,
_tickness(tickness),
_closed(closed),
_extrusionDirection(extrusionDirection) {
generateEntities();
}
LWPolyline::LWPolyline(const LWPolyline_CSPtr other, bool sameID) : CADEntity(other, sameID),
@@ -35,6 +40,7 @@ LWPolyline::LWPolyline(const LWPolyline_CSPtr other, bool sameID) : CADEntity(ot
_tickness(other->_tickness),
_closed(other->_closed),
_extrusionDirection(other->_extrusionDirection) {
generateEntities();
}
CADEntity_CSPtr LWPolyline::move(const geo::Coordinate &offset) const {
@@ -84,28 +90,17 @@ CADEntity_CSPtr LWPolyline::scale(const geo::Coordinate &scale_center, const geo
}
const geo::Area LWPolyline::boundingBox() const {
auto &&items = asGeometrics();
// TODO To think about: Currently I use dynamic_pointer_cast because I didn't want virtual function
// on the Base class of geometric entities, I like them to be 'stand alone' as much as possible
// If we see we start to do dynamic_pointer_cast more frequently w emay he to re-consider
geo::Area area;
if (auto vector = std::dynamic_pointer_cast<const geo::Vector>(items.front())) {
area = geo::Area(vector->start(), vector->end());
} else if (auto arc = std::dynamic_pointer_cast<const geo::Arc>(items.front())) {
area = arc->boundingBox();
} else {
std::cerr << "Unknown entity found in LWPolyline during boundingBox front generation " << std::endl;
if(_entities.size() == 0) {
return geo::Area();
}
for (auto geoItem : items) {
if (auto vector = std::dynamic_pointer_cast<const geo::Vector>(geoItem)) {
area = area.merge(geo::Area(vector->start(), vector->end()));
} else if (auto arc = std::dynamic_pointer_cast<const geo::Arc>(geoItem)) {
area = area.merge(arc->boundingBox());
} else {
std::cerr << "Unknown entity found in LWPolyline during boundingBox generation" << std::endl;
}
auto it = _entities.begin();
geo::Area area = (*it)->boundingBox();
it++;
while(it != _entities.end()) {
area = area.merge((*it)->boundingBox());
it++;
}
return area;
@@ -128,18 +123,21 @@ CADEntity_CSPtr LWPolyline::modify(Layer_CSPtr layer, const MetaInfo_CSPtr metaI
return newEntity;
}
std::vector<std::shared_ptr<const geo::Base>> const LWPolyline::asGeometrics() const {
std::vector<std::shared_ptr<const geo::Base>> items;
void LWPolyline::generateEntities() {
auto itr = _vertex.begin();
auto lastPoint = itr;
itr++;
while (itr != vertex().end()) {
if (lastPoint->bulge() != 0.) {
auto &&arc = geo::Arc::createArcBulge(lastPoint->location(), itr->location(), lastPoint->bulge());
items.push_back(std::make_shared<const geo::Arc>(std::move(arc)));
} else {
items.push_back(std::make_shared<const geo::Vector>(lastPoint->location(), itr->location()));
_entities.push_back(std::make_shared<const Arc>(
geo::Arc::createArcBulge(lastPoint->location(), itr->location(), lastPoint->bulge()),
layer(),
metaInfo(),
block()
));
}
else {
_entities.push_back(std::make_shared<const Line>(lastPoint->location(), itr->location(), layer(), metaInfo(), block()));
}
lastPoint = itr;
itr++;
@@ -148,21 +146,25 @@ std::vector<std::shared_ptr<const geo::Base>> const LWPolyline::asGeometrics() c
if (_closed) {
auto firstP = _vertex.begin();
if (lastPoint->bulge() != 0.) {
auto &&arc = geo::Arc::createArcBulge(lastPoint->location(), firstP->location(), lastPoint->bulge());
items.push_back(std::make_shared<const geo::Arc>(std::move(arc)));
} else {
items.push_back(std::make_shared<const geo::Vector>(lastPoint->location(), firstP->location()));
_entities.push_back(std::make_shared<const Arc>(
geo::Arc::createArcBulge(lastPoint->location(), firstP->location(), lastPoint->bulge()),
layer(),
metaInfo(),
block()
));
}
else {
_entities.push_back(std::make_shared<const Line>(lastPoint->location(), firstP->location(), layer(), metaInfo(), block()));
}
}
return items;
}
std::vector<EntityCoordinate> LWPolyline::snapPoints(const geo::Coordinate &coord, const SimpleSnapConstrain &constrain,
double minDistanceToSnap,
int maxNumberOfSnapPoints) const {
std::vector<EntityCoordinate> points;
if (constrain.constrain() & SimpleSnapConstrain::LOGICAL) {
const auto &&entities = asGeometrics();
const auto &&entities = asEntities();
for (auto &geoItem : entities) {
if (auto vector = std::dynamic_pointer_cast<const geo::Vector>(geoItem)) {
points.emplace_back(vector->start(), -1);
@@ -231,7 +233,7 @@ geo::Coordinate LWPolyline::nearestPointOnPath(const geo::Coordinate &coord) con
std::tuple<geo::Coordinate, std::shared_ptr<const geo::Vector>, std::shared_ptr<const geo::Arc>> LWPolyline::nearestPointOnPath2(
const geo::Coordinate &coord) const {
const auto &&entities = asGeometrics();
const auto &&entities = asEntities();
double minimumDistance = std::numeric_limits<double>::max();
std::shared_ptr<const geo::Vector> nearestVector = nullptr;
@@ -292,4 +294,8 @@ CADEntity_CSPtr LWPolyline::setDragPoints(std::map<unsigned int, lc::geo::Coordi
catch(std::out_of_range& e) {
return shared_from_this();
}
}
}
std::vector<CADEntity_CSPtr> const LWPolyline::asEntities() const {
return _entities;
}
@@ -144,57 +144,18 @@ namespace lc {
std::tuple<geo::Coordinate, std::shared_ptr<const geo::Vector>, std::shared_ptr<const geo::Arc>> nearestPointOnPath2(const geo::Coordinate &coord) const;
private:
/**
* @brief Generate entities of the polyline
*/
void generateEntities();
const std::vector<LWVertex2D> _vertex;
const double _width;
const double _elevation;
const double _tickness;
const bool _closed; // If we had more 'flag' options we shoudl consuder using a enum instead of seperate variables to make constructors easer
const geo::Coordinate _extrusionDirection;
// LW LWPolyline this seems to be the facto standard
// int vertexnum; /*!< number of vertex, code 90 */
// int flags; /*!< LWPolyline flag, code 70, default 0 */
// double width; /*!< constant width, code 43 */
// double elevation; /*!< elevation, code 38 */
// double thickness; /*!< thickness, code 39 */
// DRW_Coord extPoint; /*!< Dir extrusion normal vector, code 210, 220 & 230 */
// std::vector<DRW_LWVertex2D *> vertlist; /*!< vertex list */
//DRW_LWVertex2D
//double x; /*!< x geo::Coordinate, code 10 */
//double y; /*!< y geo::Coordinate, code 20 */
//double stawidth; /*!< Start width, code 40 */
//double endwidth; /*!< End width, code 41 */
//double bulge; /*!< bulge, code 42 */
// LWPolyline
//int flags; /*!< LWPolyline flag, code 70, default 0 */
//double defstawidth; /*!< Start width, code 40, default 0 */
//double defendwidth; /*!< End width, code 41, default 0 */
//int vertexcount; /*!< polygon mesh M vertex or polyface vertex num, code 71, default 0 */
//int facecount; /*!< polygon mesh N vertex or polyface face num, code 72, default 0 */
//int smoothM; /*!< smooth surface M density, code 73, default 0 */
//int smoothN; /*!< smooth surface M density, code 74, default 0 */
//int curvetype; /*!< curves & smooth surface type, code 75, default 0 */
//std::vector<DRW_Vertex *> vertlist; /*!< vertex list */
//DRW_Vertex
//double stawidth; /*!< Start width, code 40 */
//double endwidth; /*!< End width, code 41 */
//double bulge; /*!< bulge, code 42 */
//int flags; /*!< vertex flag, code 70, default 0 */
//double tgdir; /*!< curve fit tangent direction, code 50 */
//int vindex1; /*!< polyface mesh vertex index, code 71, default 0 */
//int vindex2; /*!< polyface mesh vertex index, code 72, default 0 */
//int vindex3; /*!< polyface mesh vertex index, code 73, default 0 */
//int vindex4; /*!< polyface mesh vertex index, code 74, default 0 */
//int identifier; /*!< vertex identifier, code 91, default 0 */
std::vector<CADEntity_CSPtr> _entities;
public:
/**
@@ -242,15 +203,10 @@ namespace lc {
virtual CADEntity_CSPtr modify(Layer_CSPtr layer, const MetaInfo_CSPtr metaInfo, Block_CSPtr block) const override;
/**
* Return a vector of geometry entities for this polyline
* The vector will contain geo::vector and geo::Arc items
* In the current implementation no caching of the bounding box is done
* If we see that bounding box calcualtion takes up a lot of time we
* can consider calculating the bounding box in the constructor
* and just return the cached result. We also use this for snapPoint's
* and if performance is a issue, we can cache it.
*/
std::vector<std::shared_ptr<const geo::Base>> const asGeometrics() const;
* Return a vector of entities for this polyline
* The vector will contain entity::vector and entity::Arc items
*/
std::vector<CADEntity_CSPtr> const asEntities() const;
public:
Oops, something went wrong.

0 comments on commit 3f691b7

Please sign in to comment.