Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
Plugin-Plane
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
OpenFlipper-Free
Plugin-Plane
Commits
93c8b2e3
"README.md" did not exist on "cb7889f8664b44ab8bdf0af6d24c0fade5a264bd"
Commit
93c8b2e3
authored
4 years ago
by
Zain Selman
Browse files
Options
Downloads
Patches
Plain Diff
scaling without position change follows cursor perfectly
parent
13bf1b9a
No related branches found
No related tags found
1 merge request
!2
Plane interaction
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
PlanePlugin.cc
+118
-51
118 additions, 51 deletions
PlanePlugin.cc
PlanePlugin.hh
+122
-118
122 additions, 118 deletions
PlanePlugin.hh
with
240 additions
and
169 deletions
PlanePlugin.cc
+
118
−
51
View file @
93c8b2e3
...
...
@@ -97,6 +97,70 @@ void PlanePlugin::slotKeyReleaseEvent(QKeyEvent *_event) {
* @param _event the event that occured
*/
void
PlanePlugin
::
slotMouseEvent
(
QMouseEvent
*
_event
)
{
// auto determinant = [](ACG::Vec3f const &c1, ACG::Vec3f const &c2,
// ACG::Vec3f const &c3) -> float {
// return (c1[0] * c2[1] * c3[2]) + (c2[0] * c3[1] * c1[2]) +
// (c3[0] * c1[1] * c2[2]) - (c3[0] * c2[1] * c1[2]) -
// (c2[0] * c1[1] * c3[2]) - (c1[0] * c3[1] * c2[2]);
// };
/// only works in constrained cases
// auto rayPlaneIntersection =
// [&determinant](ACG::Vec3f const &s1, ACG::Vec3f const &s2,
// ACG::Vec3f const &p, ACG::Vec3f const &q,
// ACG::Vec3f const &r, float &alpha, float &beta) {
// /// implementation of cramers rule to compute closed form
// solution for
// /// plane ray intersections (closed form solution) problematic
// if ray
// /// points away or converges to parallel to plane
// /// s1 and s2 are two points that define the ray (origin &
// origin+dir)
// /// p,q,r span a triangle that defines the plane
// /// alpha & beta are return params for the barycentric
// coordinates
// /// alpha belongs to p, beta belongs to q
// const auto denom = determinant(s1, r - p, r - q);
// alpha = determinant(s1, r - s2, r - q) / denom;
// beta = determinant(s1, r - p, r - s2) / denom;
// };
/// modification of triangleIntersection
auto
rayPlaneIntersection
=
[](
ACG
::
Vec3d
const
&
origin
,
ACG
::
Vec3d
const
&
dir
,
ACG
::
Vec3d
const
&
p
,
ACG
::
Vec3d
const
&
q
,
ACG
::
Vec3d
const
&
r
,
double
&
alpha
,
double
&
beta
)
->
bool
{
{
ACG
::
Vec3d
edge1
,
edge2
,
tvec
,
pvec
,
qvec
;
double
det
,
inv_det
;
edge1
=
q
-
p
;
edge2
=
r
-
p
;
pvec
=
dir
%
edge2
;
det
=
edge1
|
pvec
;
constexpr
double
EPSILON
=
std
::
numeric_limits
<
double
>::
epsilon
()
*
1e2
;
if
(
det
>
-
EPSILON
&&
det
<
EPSILON
)
return
false
;
inv_det
=
1.
f
/
det
;
tvec
=
origin
-
p
;
alpha
=
(
tvec
|
pvec
)
*
inv_det
;
qvec
=
tvec
%
edge1
;
beta
=
(
dir
|
qvec
)
*
inv_det
;
/// we don't really care about legal barycentric coordinates, however if
/// you really want to know if you are inside the defining triangle,
/// there you go
if
(
alpha
<
0.0
||
alpha
>
1.0
)
return
false
;
if
(
beta
<
0.0
||
alpha
+
beta
>
1.0
)
return
false
;
return
true
;
}
};
if
(
PluginFunctions
::
pickMode
()
==
PLANE
)
createPlane_
->
slotMouseEvent
(
_event
);
if
(
PluginFunctions
::
pickMode
()
==
PLANE_RESIZE
)
{
...
...
@@ -114,24 +178,19 @@ void PlanePlugin::slotMouseEvent(QMouseEvent *_event) {
lastObjId_
=
obj
->
id
();
if
(
curPlane_
)
{
origPlane_
=
curPlane_
->
plane
();
QPoint
position
=
_event
->
pos
();
/// view coords in screenspace, with flipped y-axis
/// view coords in screenspace, with flipped y-axis at depth of
/// plane
ACG
::
Vec3d
viewCoords
=
ACG
::
Vec3d
(
position
.
x
(),
PluginFunctions
::
viewerProperties
().
glState
().
context_height
()
-
position
.
y
(),
0
.5
);
.5
);
viewStartCoord_
=
viewCoords
;
/// coordinates of the point clicked in worldspace
/// however not so nice, because less precise than raycasting and
/// has issues with spheres that are actually hit
ACG
::
Vec3d
hitPoint
=
PluginFunctions
::
viewerProperties
().
glState
().
unproject
(
viewCoords
);
// Example for getting the viewing Ray
ACG
::
Vec3d
origin
;
PluginFunctions
::
viewerProperties
().
glState
().
viewing_ray
(
...
...
@@ -168,10 +227,12 @@ void PlanePlugin::slotMouseEvent(QMouseEvent *_event) {
std
::
cerr
<<
"target_idx: "
<<
target_idx
<<
std
::
endl
;
ACG
::
Vec3d
test
=
curPlane_
->
plane
().
position
-
0.5
*
curPlane_
->
plane
().
xDirection
-
0.5
*
curPlane_
->
plane
().
yDirection
;
std
::
cerr
<<
"plane 0 corner worldspace: "
<<
test
<<
std
::
endl
;
// ACG::Vec3d test = curPlane_->plane().position -
// 0.5 * curPlane_->plane().xDirection
// - 0.5 *
// curPlane_->plane().yDirection;
// std::cerr << "plane 0 corner worldspace: " << test <<
// std::endl;
if
(
target_idx
==
0
)
return
;
...
...
@@ -179,7 +240,6 @@ void PlanePlugin::slotMouseEvent(QMouseEvent *_event) {
// We hit a corner so start dragging
dragging_
=
true
;
pickedCorner_
=
target_idx
;
lastFrameCoord_
=
viewCoords
;
std
::
cerr
<<
"Picked a plane and id: "
<<
target_idx
<<
std
::
endl
;
}
...
...
@@ -199,28 +259,44 @@ void PlanePlugin::slotMouseEvent(QMouseEvent *_event) {
QPoint
position
=
_event
->
pos
();
/// view coords in screenspace, with flipped y-axis
/// matrix to transform points from image plane to curPlane_
auto
plane
=
origPlane_
;
/// view coords in worldspace, with flipped y-axis
const
auto
viewCoord
=
ACG
::
Vec3d
(
position
.
x
(),
PluginFunctions
::
viewerProperties
().
glState
().
context_height
()
-
position
.
y
(),
0.5
);
const
auto
screenSpaceDiff
=
viewCoord
-
lastFrameCoord_
;
.5
);
/// matrix to transform points from image plane to curPlane_
auto
&
plane
=
curPlane_
->
plane
();
// ACG::GLMatrixf mvp =
// PluginFunctions::viewerProperties().glState().modelview();
// const auto dragStart = mvp.transform_point(viewStartCoord);
// const auto dragEnd = mvp.transform_point(viewCoord);
// const auto update = dragEnd - dragStart;
// const auto cen = mvp.transform_point(ACG::Vec3d{0,0,0});
// std::cerr << "################\nplane center: " <<
// plane.position << std::endl; std::cerr << "center: " << cen
// << std::endl; std::cerr << "drag start: " << dragStart <<
// std::endl; std::cerr << "drag end: " << dragEnd <<
// std::endl;
/// get the world position by intersecting plane equation with ray
ACG
::
Vec3d
origin
;
ACG
::
Vec3d
dir
;
PluginFunctions
::
viewerProperties
().
glState
().
viewing_ray
(
viewCoord
[
0
],
viewCoord
[
1
],
origin
,
dir
);
{
double
u
=
-
3.1415926539
,
v
=
-
3.1415926539
;
const
auto
center
=
plane
.
position
;
const
auto
xdir
=
plane
.
xDirection
/
2.
;
const
auto
ydir
=
plane
.
yDirection
/
2.
;
const
auto
p0
=
ACG
::
Vec3d
{
center
+
xdir
+
ydir
};
const
auto
p1
=
ACG
::
Vec3d
{
center
+
xdir
-
ydir
};
const
auto
p2
=
ACG
::
Vec3d
{
center
-
xdir
-
ydir
};
/// we can assume that most of the time, there wont be an
/// intersection. but as we only check one half of the triangle, the
/// other will always be outside
/// we dont really care about the result here
rayPlaneIntersection
(
origin
,
dir
,
p0
,
p1
,
p2
,
u
,
v
);
const
auto
w
=
1.
-
(
u
+
v
);
currWorldPos_
=
(
w
*
p0
)
+
(
u
*
p1
)
+
(
v
*
p2
);
}
const
auto
worldSpaceUpdate
=
(
currWorldPos_
-
result_
)
/
1.
;
/// update to corresponding corner later
const
auto
distClickOrigin
=
plane
.
position
+
(
.5
f
*
plane
.
xDirection
)
+
(
.5
f
*
plane
.
yDirection
);
/// we want to scale our plane, we will do so in 3 steps:
/// 1. translate to origin
...
...
@@ -230,13 +306,6 @@ void PlanePlugin::slotMouseEvent(QMouseEvent *_event) {
/// 5. translate back to updated target position (old origin +
/// .5*updatevector
const
auto
lastWorldSpace
=
PluginFunctions
::
viewerProperties
().
glState
().
unproject
(
lastFrameCoord_
);
const
auto
currWorldSpace
=
PluginFunctions
::
viewerProperties
().
glState
().
unproject
(
viewCoord
);
const
auto
diffWorldSpace
=
currWorldSpace
-
lastWorldSpace
;
/// 1. transform to origin
auto
transform
=
ACG
::
GLMatrixf
(
ACG
::
Matrix4x4f
());
transform
.
identity
();
...
...
@@ -253,23 +322,27 @@ void PlanePlugin::slotMouseEvent(QMouseEvent *_event) {
/// 3. scale by half updates length
/// todo: adjust to screen space
ACG
::
Vec3f
scale
=
ACG
::
Vec3f
{
screenSpaceDiff
};
scale
[
0
]
=
(
scale
[
0
]
/
(
scale
[
0
]
+
500
))
+
1
;
scale
[
1
]
=
(
scale
[
1
]
/
(
scale
[
1
]
+
500
))
+
1
;
scale
[
2
]
=
.0
f
;
auto
scale
=
ACG
::
Vec3f
{(
worldSpaceUpdate
+
distClickOrigin
)
/
distClickOrigin
};
scale
[
2
]
=
1
;
/// we dont do anything in z-dir
transform
.
scale
(
scale
);
std
::
cerr
<<
"scale: "
<<
scale
<<
std
::
endl
;
/// 4. rotate back
// transform.rotate(-angle, n0.cross(n1));
/// 4. translate back
transform
.
translate
(
ACG
::
Vec3f
{
plane
.
position
});
transform
.
translate
(
ACG
::
Vec3f
{
diffW
orldSpace
/
2
});
//
transform.translate(ACG::Vec3f{
w
orldSpace
Update
/ 2});
plane
.
transform
(
transform
);
std
::
cerr
<<
"new pos: "
<<
plane
.
position
<<
std
::
endl
;
std
::
cerr
<<
"worldSpaceUpdate: "
<<
worldSpaceUpdate
<<
std
::
endl
;
std
::
cerr
<<
"[world] start pos: "
<<
result_
<<
std
::
endl
;
std
::
cerr
<<
"[world] curr pos: "
<<
currWorldPos_
<<
std
::
endl
;
std
::
cerr
<<
"[world] plane.pos: "
<<
plane
.
position
<<
std
::
endl
;
std
::
cerr
<<
"scale: "
<<
scale
<<
std
::
endl
;
curPlane_
->
plane
()
=
plane
;
/// overwrite plane
/// 0 corner
if
(
pickedCorner_
==
1
)
{
...
...
@@ -279,9 +352,6 @@ void PlanePlugin::slotMouseEvent(QMouseEvent *_event) {
}
/// xy corner
if
(
pickedCorner_
==
3
)
{
// plane.setPlane(plane.position, plane.xDirection * 1.1,
// plane.yDirection * 1.1f); std::cerr << "plane pos: "
// << plane.position << std::endl;
}
/// y corner
if
(
pickedCorner_
==
4
)
{
...
...
@@ -289,8 +359,6 @@ void PlanePlugin::slotMouseEvent(QMouseEvent *_event) {
if
(
lastObjId_
>
0
)
emit
updatedObject
(
lastObjId_
,
UPDATE_GEOMETRY
);
lastFrameCoord_
=
viewCoord
;
}
break
;
...
...
@@ -303,7 +371,6 @@ void PlanePlugin::slotMouseEvent(QMouseEvent *_event) {
pickedCorner_
=
0
;
result_
=
ACG
::
Vec3d
{
.0
};
viewStartCoord_
=
ACG
::
Vec3d
{
.0
};
lastFrameCoord_
=
ACG
::
Vec3d
{
.0
};
curPlane_
=
nullptr
;
lastObjId_
=
-
1
;
...
...
This diff is collapsed.
Click to expand it.
PlanePlugin.hh
+
122
−
118
View file @
93c8b2e3
...
...
@@ -3,23 +3,29 @@
#include
<QObject>
#include
<ObjectTypes/Plane/Plane.hh>
#include
<ObjectTypes/Plane/QtPlaneSelect.hh>
#include
<ObjectTypes/PolyMesh/PolyMesh.hh>
#include
<ObjectTypes/TriangleMesh/TriangleMesh.hh>
#include
<OpenFlipper/BasePlugin/BaseInterface.hh>
#include
<OpenFlipper/BasePlugin/MouseInterface.hh>
#include
<OpenFlipper/BasePlugin/KeyInterface.hh>
#include
<OpenFlipper/BasePlugin/
Picking
Interface.hh>
#include
<OpenFlipper/BasePlugin/
LoadSave
Interface.hh>
#include
<OpenFlipper/BasePlugin/LoggingInterface.hh>
#include
<OpenFlipper/BasePlugin/MouseInterface.hh>
#include
<OpenFlipper/BasePlugin/PickingInterface.hh>
#include
<OpenFlipper/BasePlugin/ScriptInterface.hh>
#include
<OpenFlipper/BasePlugin/ToolbarInterface.hh>
#include
<OpenFlipper/BasePlugin/LoadSaveInterface.hh>
#include
<OpenFlipper/common/Types.hh>
#include
<ObjectTypes/PolyMesh/PolyMesh.hh>
#include
<ObjectTypes/TriangleMesh/TriangleMesh.hh>
#include
<ObjectTypes/Plane/Plane.hh>
#include
<ObjectTypes/Plane/QtPlaneSelect.hh>
class
PlanePlugin
:
public
QObject
,
BaseInterface
,
MouseInterface
,
KeyInterface
,
PickingInterface
,
LoggingInterface
,
ToolbarInterface
,
ScriptInterface
,
LoadSaveInterface
{
class
PlanePlugin
:
public
QObject
,
BaseInterface
,
MouseInterface
,
KeyInterface
,
PickingInterface
,
LoggingInterface
,
ToolbarInterface
,
ScriptInterface
,
LoadSaveInterface
{
Q_OBJECT
Q_INTERFACES
(
BaseInterface
)
Q_INTERFACES
(
MouseInterface
)
...
...
@@ -32,7 +38,6 @@ class PlanePlugin : public QObject, BaseInterface, MouseInterface, KeyInterface,
Q_PLUGIN_METADATA
(
IID
"org.OpenFlipper.Plugins.Plugin-Plane"
)
signals:
// BaseInterface
void
updateView
();
...
...
@@ -53,7 +58,8 @@ class PlanePlugin : public QObject, BaseInterface, MouseInterface, KeyInterface,
void
defineViewMode
(
QString
_mode
,
QStringList
_usedWidgets
);
// KeyInterfae
void
registerKey
(
int
_key
,
Qt
::
KeyboardModifiers
_modifiers
,
QString
_description
,
bool
_multiUse
=
false
);
void
registerKey
(
int
_key
,
Qt
::
KeyboardModifiers
_modifiers
,
QString
_description
,
bool
_multiUse
=
false
);
// PickingInterface
void
addPickMode
(
const
std
::
string
_mode
);
...
...
@@ -65,7 +71,6 @@ class PlanePlugin : public QObject, BaseInterface, MouseInterface, KeyInterface,
void
log
(
Logtype
_type
,
QString
_message
);
void
log
(
QString
_message
);
private
slots
:
// BaseInterface
...
...
@@ -81,8 +86,8 @@ class PlanePlugin : public QObject, BaseInterface, MouseInterface, KeyInterface,
// KeyInterface:
void
slotKeyReleaseEvent
(
QKeyEvent
*
_event
);
bool
getIntersectionParams
(
BaseObjectData
&
_obj
,
ACG
::
Vec3d
&
_center
,
double
&
_radius
);
bool
getIntersectionParams
(
BaseObjectData
&
_obj
,
ACG
::
Vec3d
&
_center
,
double
&
_radius
);
public:
PlanePlugin
();
...
...
@@ -100,16 +105,15 @@ class PlanePlugin : public QObject, BaseInterface, MouseInterface, KeyInterface,
/// get the points from the intersection between mesh and plane
template
<
class
MeshT
>
std
::
vector
<
ACG
::
Vec3d
>
getIntersectionPoints
(
MeshT
*
_mesh
,
uint
_fh
,
ACG
::
Vec3d
_planeNormal
,
ACG
::
Vec3d
_planePoint
,
bool
&
_closed
);
std
::
vector
<
ACG
::
Vec3d
>
getIntersectionPoints
(
MeshT
*
_mesh
,
uint
_fh
,
ACG
::
Vec3d
_planeNormal
,
ACG
::
Vec3d
_planePoint
,
bool
&
_closed
);
/// get an edge of the mesh that is cut by the plane
template
<
class
MeshT
>
typename
MeshT
::
EdgeHandle
getCuttedEdge
(
MeshT
&
_mesh
,
ACG
::
Vec3d
&
_planeNormal
,
ACG
::
Vec3d
&
_planePoint
);
typename
MeshT
::
EdgeHandle
getCuttedEdge
(
MeshT
&
_mesh
,
ACG
::
Vec3d
&
_planeNormal
,
ACG
::
Vec3d
&
_planePoint
);
/** @} */
...
...
@@ -125,7 +129,6 @@ class PlanePlugin : public QObject, BaseInterface, MouseInterface, KeyInterface,
/// Create a plane node when position/normal have been drawn
void
slotCreatePlaneTriggered
();
private
:
// Plane Selection Tools
QtPlaneSelect
*
createPlane_
;
...
...
@@ -140,12 +143,13 @@ class PlanePlugin : public QObject, BaseInterface, MouseInterface, KeyInterface,
// world space coords of the dragging start position (through raycast)
ACG
::
Vec3d
result_
{
.0
};
ACG
::
Vec3d
currWorldPos_
{
.0
};
// view space coords of the dragging start position
ACG
::
Vec3d
viewStartCoord_
{
.0
};
ACG
::
Vec3d
lastFrameCoord_
{
.0
};
ACG
::
Vec3d
viewDirection_
{
.0
};
// currently dragged plane
PlaneObject
*
curPlane_
=
nullptr
;
Plane
origPlane_
;
int
lastObjId_
=
-
1
;
/** @} */
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment