Skip to content

Commit 94e5f0c

Browse files
committed
line segment intersector added; line segment selection interaction added
1 parent 5ca8032 commit 94e5f0c

File tree

6 files changed

+174
-1
lines changed

6 files changed

+174
-1
lines changed

src/libSGControls/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ set (libSGControls_SRCS
2626
EditEntityCommand.cpp
2727
StrokeIntersector.h
2828
StrokeIntersector.cpp
29+
Entity2DIntersector.h
2930
LineIntersector.h
3031
LineIntersector.cpp
3132
PolyLineIntersector.h
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#ifndef ENTITY2DINTERSECTOR_H
2+
#define ENTITY2DINTERSECTOR_H
3+
4+
#include <vector>
5+
6+
#include <osg/ref_ptr>
7+
#include <osgUtil/LineSegmentIntersector>
8+
9+
#include "Utilities.h"
10+
11+
// TODO: instead of using intersectors for each entity type, use this one with
12+
// provided template, e.g. entity::Stroke, entity::Photo, etc.
13+
14+
template <typename EntityType>
15+
class Entity2DIntersector : public osgUtil::LineSegmentIntersector
16+
{
17+
public:
18+
Entity2DIntersector()
19+
: osgUtil::LineSegmentIntersector(MODEL, 0.f, 0.f)
20+
, m_offset(0.05f)
21+
{
22+
m_hitIndices.clear();
23+
}
24+
25+
Entity2DIntersector(const osg::Vec3& start, const osg::Vec3& end)
26+
: osgUtil::LineSegmentIntersector(start, end)
27+
, m_offset(0.05f)
28+
{
29+
m_hitIndices.clear();
30+
}
31+
32+
Entity2DIntersector(CoordinateFrame cf, double x, double y)
33+
: osgUtil::LineSegmentIntersector(cf, x, y)
34+
, m_offset(0.05f)
35+
{
36+
m_hitIndices.clear();
37+
}
38+
39+
Entity2DIntersector(CoordinateFrame cf, const osg::Vec3d& start, const osg::Vec3d& end)
40+
: osgUtil::LineSegmentIntersector(cf, start, end)
41+
, m_offset(0.05f)
42+
{
43+
m_hitIndices.clear();
44+
}
45+
46+
void setOffset(float offset)
47+
{
48+
m_offset = offset;
49+
}
50+
51+
float getOffset() const
52+
{
53+
return m_offset;
54+
}
55+
56+
void getHitIndices(int& first, int& last) const
57+
{
58+
if (m_hitIndices.empty()){
59+
first = -1;
60+
last = -1;
61+
}
62+
else {
63+
first = m_hitIndices.front();
64+
last = m_hitIndices.back();
65+
}
66+
}
67+
68+
virtual Intersector* clone( osgUtil::IntersectionVisitor& iv )
69+
{
70+
if ( _coordinateFrame==MODEL && iv.getModelMatrix()==0 )
71+
{
72+
osg::ref_ptr<Entity2DIntersector> cloned = new Entity2DIntersector( _start, _end );
73+
cloned->_parent = this;
74+
cloned->m_offset = m_offset;
75+
return cloned.release();
76+
}
77+
78+
osg::Matrix matrix;
79+
switch ( _coordinateFrame )
80+
{
81+
case WINDOW:
82+
if (iv.getWindowMatrix()) matrix.preMult( *iv.getWindowMatrix() );
83+
if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() );
84+
if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() );
85+
if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() );
86+
break;
87+
case PROJECTION:
88+
if (iv.getProjectionMatrix()) matrix.preMult( *iv.getProjectionMatrix() );
89+
if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() );
90+
if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() );
91+
break;
92+
case VIEW:
93+
if (iv.getViewMatrix()) matrix.preMult( *iv.getViewMatrix() );
94+
if (iv.getModelMatrix()) matrix.preMult( *iv.getModelMatrix() );
95+
break;
96+
case MODEL:
97+
if (iv.getModelMatrix()) matrix = *iv.getModelMatrix();
98+
break;
99+
}
100+
101+
osg::Matrix inverse = osg::Matrix::inverse(matrix);
102+
osg::ref_ptr<Entity2DIntersector> cloned = new Entity2DIntersector( _start*inverse, _end*inverse );
103+
cloned->_parent = this;
104+
cloned->m_offset = m_offset;
105+
return cloned.release();
106+
}
107+
108+
virtual void intersect( osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable )
109+
{
110+
osg::BoundingBox bb = drawable->getBoundingBox();
111+
bb.xMin() -= m_offset; bb.xMax() += m_offset;
112+
bb.yMin() -= m_offset; bb.yMax() += m_offset;
113+
bb.zMin() -= m_offset; bb.zMax() += m_offset;
114+
115+
osg::Vec3d s(_start), e(_end);
116+
if (!intersectAndClip(s, e, bb)) return;
117+
if (iv.getDoDummyTraversal()) return;
118+
119+
EntityType* geometry = dynamic_cast<EntityType*>(drawable->asGeometry());
120+
if (geometry)
121+
{
122+
osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometry->getVertexArray());
123+
if (!vertices) return;
124+
125+
for (unsigned int i=1; i<vertices->size(); ++i)
126+
{
127+
128+
double distance = Utilities::getSkewLinesDistance(s,e,(*vertices)[i], (*vertices)[i-1]);
129+
130+
if (m_offset<distance) continue;
131+
132+
Intersection hit;
133+
hit.ratio = distance;
134+
hit.nodePath = iv.getNodePath();
135+
hit.drawable = drawable;
136+
hit.matrix = iv.getModelMatrix();
137+
hit.localIntersectionPoint = (*vertices)[i];
138+
m_hitIndices.push_back(i);
139+
insertIntersection(hit);
140+
}
141+
}
142+
}
143+
144+
protected:
145+
virtual ~Entity2DIntersector(){}
146+
147+
private:
148+
float m_offset;
149+
std::vector<unsigned int> m_hitIndices;
150+
};
151+
152+
#endif // ENTITY2DINTERSECTOR_H

src/libSGControls/EventHandler.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,15 @@ void EventHandler::doSelectEntity(const osgGA::GUIEventAdapter &ea, osgGA::GUIAc
13371337
if (stroke) canvas->addEntitySelected(stroke);
13381338
}
13391339

1340+
Entity2DIntersector<entity::LineSegment>::Intersection result_segment;
1341+
bool inter_segment = this->getIntersection< Entity2DIntersector<entity::LineSegment>::Intersection,
1342+
Entity2DIntersector<entity::LineSegment> >(ea, aa, cher::MASK_CANVAS_IN, result_segment);
1343+
if (inter_segment){
1344+
entity::LineSegment* segment = this->getEntity2D<entity::LineSegment>(result_segment);
1345+
if (segment)
1346+
canvas->addEntitySelected(segment);
1347+
}
1348+
13401349
/* if some entities were selected, go into edit-frame mode for canvas frame */
13411350
if (ea.getEventType() == osgGA::GUIEventAdapter::RELEASE){
13421351
canvas->updateFrame(m_scene->getCanvasPrevious());

src/libSGControls/EventHandler.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "UserScene.h"
2727
#include "RootScene.h"
2828
#include "StrokeIntersector.h"
29+
#include "Entity2DIntersector.h"
2930
#include "LineIntersector.h"
3031
#include "PolyLineIntersector.h"
3132
#include "PointIntersector.h"
@@ -142,6 +143,12 @@ class EventHandler : public osgGA::GUIEventHandler {
142143
/*! A method to obtain entity::Stroke type from intersection result. */
143144
entity::Stroke* getStroke(const StrokeIntersector::Intersection& result);
144145

146+
template <typename EntityType>
147+
EntityType* getEntity2D(const Entity2DIntersector<entity::Entity2D>::Intersection& result)
148+
{
149+
return dynamic_cast<EntityType*>(result.drawable.get());
150+
}
151+
145152
/*! A method to obtain entity::Canvas type from intersection result. */
146153
entity::Canvas* getCanvas(const osgUtil::LineSegmentIntersector::Intersection& result);
147154

src/libSGEntities/Canvas.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,9 @@ void entity::Canvas::addEntitySelected(Entity2D *entity)
575575
case cher::ENTITY_PHOTO:
576576
m_selectedGroup.addEntity(entity, m_geodePhotos.get());
577577
break;
578+
case cher::ENTITY_LINESEGMENT:
579+
m_selectedGroup.addEntity(entity, m_geodeLineSegments.get());
580+
break;
578581
default:
579582
break;
580583
}

src/libSGEntities/UserScene.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1336,7 +1336,8 @@ void entity::UserScene::linesegmentFinish(QUndoStack *stack)
13361336
Q_CHECK_PTR(segment_clone.get());
13371337
if (segment_clone->copyFrom(segment)){
13381338
segment_clone->redefineToShape();
1339-
fur::AddLineSegmentCommand* cmd = new fur::AddLineSegmentCommand(this, segment_clone);
1339+
// TODO: replace add stroke, photo and polygon with add entity command
1340+
fur::AddEntityCommand* cmd = new fur::AddEntityCommand(this, segment_clone);
13401341
Q_CHECK_PTR(cmd);
13411342
stack->push(cmd);
13421343
}

0 commit comments

Comments
 (0)