Initial implementation of rotation in GeometryView

This commit is contained in:
brunoherbelin
2020-05-16 13:41:08 +02:00
parent 4527d0dd1f
commit 22a6dc63e9
7 changed files with 447 additions and 82 deletions

View File

@@ -266,7 +266,7 @@ set(VMIX_RSC_FILES
./rsc/mesh/border_round.ply
./rsc/mesh/border_sharp.ply
./rsc/mesh/border_large_round.ply
./rsc/mesh/border_handles_sharp.ply
./rsc/mesh/border_handles_rotation.ply
./rsc/mesh/border_handles_overlay.ply
./rsc/mesh/border_large_sharp.ply
./rsc/mesh/border_vertical_overlay.ply

View File

@@ -456,7 +456,11 @@ void Frame::accept(Visitor& v)
Handles::Handles(Type type) : Node(), type_(type)
{
color = glm::vec4( 1.f, 1.f, 1.f, 1.f);
handle_ = new Mesh("mesh/border_handles_overlay.ply");
if ( type_ == ROTATE )
handle_ = new Mesh("mesh/border_handles_rotation.ply");
else
handle_ = new Mesh("mesh/border_handles_overlay.ply");
}
Handles::~Handles()
@@ -517,7 +521,10 @@ void Handles::draw(glm::mat4 modelview, glm::mat4 projection)
handle_->draw( ctm, projection );
}
else if ( type_ == ROTATE ){
// only once in upper top right corner
ctm = modelview * glm::translate(glm::identity<glm::mat4>(), glm::vec3(ar + 0.06f, +1.06f, 0.f));
ctm[0][0] = ctm[1][1] = ctm[2][2] = 1.f;
handle_->draw( ctm, projection );
}
}
}

View File

@@ -99,7 +99,8 @@ void PickingVisitor::visit(Handles &n)
bb.translated(glm::vec3(0.f, -1.f, 0.f)).contains( glm::vec3(P) ) );
}
else if ( n.type() == Handles::ROTATE ){
// TODO Picking Rotation
// Picking Rotation icon
picked = bb.translated(glm::vec3(1.06f, +1.06f, 0.f)).contains( glm::vec3(P) );
}
if ( picked )

View File

@@ -90,8 +90,6 @@ void Source::accept(Visitor& v)
void Source::setOverlayVisible(bool on)
{
// if (overlay_)
// overlay_->visible_ = on;
for (auto o = overlays_.begin(); o != overlays_.end(); o++)
(*o).second->visible_ = on;
}
@@ -144,7 +142,7 @@ MediaSource::MediaSource(const std::string &name) : Source(name), path_("")
frame->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
overlays_[View::MIXING]->attach(frame);
// extra overlay for geometry view
// extra overlays for geometry view
frame = new Frame(Frame::SHARP_LARGE);
frame->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
frame->translation_.z = 0.1;
@@ -161,6 +159,10 @@ MediaSource::MediaSource(const std::string &name) : Source(name), path_("")
resize_V_handle_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
resize_V_handle_->translation_.z = 0.15;
overlays_[View::GEOMETRY]->attach(resize_V_handle_);
rotate_handle_ = new Handles(Handles::ROTATE);
rotate_handle_->color = glm::vec4( 0.8f, 0.8f, 0.0f, 1.f);
rotate_handle_->translation_.z = 0.15;
overlays_[View::GEOMETRY]->attach(rotate_handle_);
}
@@ -263,12 +265,15 @@ void MediaSource::render()
mediasurface_->draw(glm::identity<glm::mat4>(), projection);
renderbuffer_->end();
// ADJUST alpha based on MIXING node
// read position of the mixing node and interpret this as transparency of render output
float alpha = 1.0 - CLAMP( SQUARE( glm::length(groups_[View::MIXING]->translation_) ), 0.f, 1.f );
blendingshader_->color.a = alpha;
// TODO modify geometry
// MODIFY geometry based on GEOMETRY node
groups_[View::RENDERING]->translation_ = groups_[View::GEOMETRY]->translation_;
groups_[View::RENDERING]->scale_ = groups_[View::GEOMETRY]->scale_;
groups_[View::RENDERING]->rotation_ = groups_[View::GEOMETRY]->rotation_;
}
}

View File

@@ -2,6 +2,7 @@
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/vector_angle.hpp>
// memmove
#include <string.h>
@@ -12,10 +13,10 @@
#include "Source.h"
#include "Primitives.h"
#include "PickingVisitor.h"
#include "Resource.h"
#include "Mesh.h"
#include "Mixer.h"
#include "FrameBuffer.h"
#include "UserInterfaceManager.h"
#include "Log.h"
#define CIRCLE_PIXELS 64
@@ -194,7 +195,7 @@ RenderView::~RenderView()
void RenderView::setResolution(glm::vec3 resolution)
{
if (resolution.x < 100.f || resolution.y < 100)
if (resolution.x < 128.f || resolution.y < 128.f)
resolution = FrameBuffer::getResolutionFromParameters(Settings::application.framebuffer_ar, Settings::application.framebuffer_h);
if (frame_buffer_)
@@ -289,33 +290,38 @@ void GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node
return;
Group *sourceNode = s->group(View::GEOMETRY);
// remember
static glm::vec2 start_position = glm::vec2(0.f);
// remember source transform at moment of clic at position 'from'
static glm::vec2 start_clic_position = glm::vec2(0.f);
static glm::vec3 start_translation = glm::vec3(0.f);
static glm::vec3 start_scale = glm::vec3(1.f);
if ( start_position != from ) {
start_position = from;
static glm::vec3 start_rotation = glm::vec3(0.f);
if ( start_clic_position != from ) {
start_clic_position = from;
start_translation = sourceNode->translation_;
start_scale = sourceNode->scale_;
start_rotation = sourceNode->rotation_;
}
// grab coordinates in scene View reference frame
// grab coordinates in scene-View reference frame
glm::vec3 gl_Position_from = Rendering::manager().unProject(from, scene.root()->transform_);
glm::vec3 gl_Position_to = Rendering::manager().unProject(to, scene.root()->transform_);
// grab coordinates in source root reference frame
// grab coordinates in source-root reference frame
glm::vec4 S_from = glm::inverse(sourceNode->transform_) * glm::vec4( gl_Position_from, 1.f );
glm::vec4 S_to = glm::inverse(sourceNode->transform_) * glm::vec4( gl_Position_to, 1.f );
glm::vec3 S_resize = glm::vec3(S_to) / glm::vec3(S_from);
// Log::Info(" screen coordinates ( %.1f, %.1f ) ", to.x, to.y);
// Log::Info(" scene coordinates ( %.1f, %.1f ) ", gl_Position_to.x, gl_Position_to.y);
// Log::Info(" source coordinates ( %.1f, %.1f ) ", P_to.x, P_to.y);
// Log::Info(" source coordinates ( %.1f, %.1f, %.1f ) ", S_from.x, S_from.y, S_from.z);
// Log::Info(" ( %.1f, %.1f, %.1f ) ", S_to.x, S_to.y, S_to.z);
// which manipulation to perform?
if (pick.first) {
// picking on the resizing handles in the corners
if ( pick.first == s->handleNode(Handles::RESIZE) ) {
if (UserInterface::manager().keyboardModifier())
S_resize.y = S_resize.x;
sourceNode->scale_ = start_scale * S_resize;
}
// picking on the resizing handles left or right
@@ -326,9 +332,10 @@ void GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node
else if ( pick.first == s->handleNode(Handles::RESIZE_V) ) {
sourceNode->scale_ = start_scale * glm::vec3(1.f, S_resize.y, 1.f);
}
// TODO picking on the rotating handle
// picking on the rotating handle
else if ( pick.first == s->handleNode(Handles::ROTATE) ) {
float angle = glm::orientedAngle( glm::normalize(glm::vec2(S_from)), glm::normalize(glm::vec2(S_to)));
sourceNode->rotation_ = start_rotation + glm::vec3(0.f, 0.f, angle);
}
// picking anywhere but on a handle: user wants to move the source
else {
@@ -340,60 +347,5 @@ void GeometryView::grab (glm::vec2 from, glm::vec2 to, Source *s, std::pair<Node
sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from;
}
// // coordinate in source
// glm::mat4 modelview(1.f);
// glm::vec2 clicpos(0.f);
//// PickingVisitor pv(gl_Position_to);
//// sourceNode->accept(pv);
//// if (!pv.picked().empty()){
//// clicpos = pv.picked().back().second;
////// modelview = pv.picked().back().first->transform_;
////// Log::Info("clic pos source %.2f. %.2f", clicpos.x, clicpos.y);
//// }
// glm::vec4 P_from = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_from, 1.f );
// glm::vec4 P_to = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_to, 1.f );
//// glm::vec4 P = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_to, 1.f );
// if ( pick.first == s->handleNode(Handles::RESIZE) )
// {
// // clic inside corner
//// Log::Info("corner %.2f. %.2f", clicpos.x, clicpos.y);
////// Log::Info(" %.2f. %.2f", P.x, P.y);
////// glm::vec2 topos = clicpos;
////// PickingVisitor pv(gl_Position_from);
////// sourceNode->accept(pv);
////// if (!pv.picked().empty()){
////// topos = pv.picked().back().second;
//////// Log::Info("scale %.2f. %.2f", topos.x, topos.y);
////// }
////// glm::vec4 P = glm::inverse(sourceNode->transform_ * modelview) * glm::vec4( gl_Position_from, 1.f );
// sourceNode->scale_ = start_scale * (glm::vec3(P_to) / glm::vec3(P_from) );
//// Log::Info("scale %.2f. %.2f", sourceNode->scale_.x, sourceNode->scale_.y);
//// Log::Info(" %.2f. %.2f", start_scale.x, start_scale.y);
// }
// else if ( ABS(clicpos.x)>0.95f && ABS(clicpos.y)<0.05f )
// {
// // clic resize horizontal
// Log::Info("H resize %.2f. %.2f", clicpos.x, clicpos.y);
// }
// else if ( ABS(clicpos.x)<0.05f && ABS(clicpos.y)>0.95f )
// {
// // clic resize vertical
// Log::Info("V resize %.2f. %.2f", clicpos.x, clicpos.y);
// }
// else
// clic inside source: compute delta translation
// sourceNode->translation_ = start_translation + gl_Position_to - gl_Position_from;
}

View File

@@ -8,14 +8,14 @@ property float z
element face 8
property list uchar uint vertex_indices
end_header
0.091161 0.091238 0.000000
0.073023 -0.072006 0.000000
0.091161 -0.090145 0.000000
-0.072083 -0.072006 0.000000
-0.090222 -0.090145 0.000000
-0.090222 0.091238 0.000000
-0.072083 0.073100 0.000000
0.073023 0.073100 0.000000
0.048802 0.048843 0.000000
0.039092 -0.038548 0.000000
0.048802 -0.048258 0.000000
-0.038589 -0.038548 0.000000
-0.048299 -0.048258 0.000000
-0.048299 0.048843 0.000000
-0.038589 0.039133 0.000000
0.039092 0.039133 0.000000
3 0 1 2
3 2 3 4
3 3 5 4

View File

@@ -0,0 +1,400 @@
ply
format ascii 1.0
comment Created by Blender 2.82 (sub 7) - www.blender.org, source file: 'border_large_sharp_2.blend'
element vertex 195
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
property uchar alpha
element face 191
property list uchar uint vertex_indices
end_header
-0.067791 0.039872 0.000000 255 255 255 255
-0.044363 0.064167 0.000000 255 255 255 255
-0.055381 0.078421 0.000000 255 255 255 255
-0.004050 0.078235 0.000000 255 255 255 255
0.010498 0.077641 0.000000 255 255 255 255
0.000061 0.078344 0.000000 255 255 255 255
-0.008105 0.077912 0.000000 255 255 255 255
-0.012097 0.077381 0.000000 255 255 255 255
0.020511 0.075593 0.000000 255 255 255 255
-0.016022 0.076647 0.000000 255 255 255 255
-0.019875 0.075717 0.000000 255 255 255 255
-0.023649 0.074595 0.000000 255 255 255 255
0.030006 0.072293 0.000000 255 255 255 255
-0.027340 0.073288 0.000000 255 255 255 255
-0.030943 0.071801 0.000000 255 255 255 255
0.038892 0.067832 0.000000 255 255 255 255
-0.034452 0.070139 0.000000 255 255 255 255
-0.037862 0.068309 0.000000 255 255 255 255
-0.041167 0.066317 0.000000 255 255 255 255
0.000061 0.065520 0.000000 255 255 255 255
0.008760 0.064934 0.000000 255 255 255 255
0.047077 0.062303 0.000000 255 255 255 255
-0.003317 0.065431 0.000000 255 255 255 255
-0.006649 0.065169 0.000000 255 255 255 255
-0.009931 0.064738 0.000000 255 255 255 255
0.017104 0.063228 0.000000 255 255 255 255
-0.013158 0.064142 0.000000 255 255 255 255
-0.028328 0.058855 0.000000 255 255 255 255
-0.025436 0.060204 0.000000 255 255 255 255
-0.022469 0.061412 0.000000 255 255 255 255
-0.019431 0.062474 0.000000 255 255 255 255
-0.016326 0.063385 0.000000 255 255 255 255
0.025017 0.060478 0.000000 255 255 255 255
0.054469 0.055797 0.000000 255 255 255 255
0.032422 0.056760 0.000000 255 255 255 255
-0.031141 0.057368 0.000000 255 255 255 255
-0.033871 0.055750 0.000000 255 255 255 255
0.039243 0.052152 0.000000 255 255 255 255
0.060977 0.048406 0.000000 255 255 255 255
-0.036513 0.054004 0.000000 255 255 255 255
-0.036299 0.053726 0.000000 255 255 255 255
-0.035704 0.052957 0.000000 255 255 255 255
-0.034807 0.051796 0.000000 255 255 255 255
0.045403 0.046730 0.000000 255 255 255 255
-0.033682 0.050340 0.000000 255 255 255 255
-0.032405 0.048688 0.000000 255 255 255 255
-0.031053 0.046938 0.000000 255 255 255 255
0.066507 0.040223 0.000000 255 255 255 255
-0.029700 0.045188 0.000000 255 255 255 255
0.050826 0.040571 0.000000 255 255 255 255
-0.028423 0.043536 0.000000 255 255 255 255
-0.027298 0.042080 0.000000 255 255 255 255
-0.026401 0.040919 0.000000 255 255 255 255
-0.025807 0.040150 0.000000 255 255 255 255
0.055434 0.033752 0.000000 255 255 255 255
0.070969 0.031338 0.000000 255 255 255 255
-0.025592 0.039872 0.000000 255 255 255 255
0.059152 0.026348 0.000000 255 255 255 255
0.074270 0.021845 0.000000 255 255 255 255
-0.003418 0.026891 0.000000 255 255 255 255
0.003541 0.026891 0.000000 255 255 255 255
0.000061 0.027125 0.000000 255 255 255 255
0.006879 0.026209 0.000000 255 255 255 255
-0.006756 0.026209 0.000000 255 255 255 255
0.061902 0.018437 0.000000 255 255 255 255
0.010044 0.025109 0.000000 255 255 255 255
-0.009921 0.025109 0.000000 255 255 255 255
0.013006 0.023622 0.000000 255 255 255 255
-0.012883 0.023622 0.000000 255 255 255 255
0.015734 0.021779 0.000000 255 255 255 255
-0.015611 0.021779 0.000000 255 255 255 255
0.076318 0.011835 0.000000 255 255 255 255
0.018198 0.019610 0.000000 255 255 255 255
-0.018075 0.019610 0.000000 255 255 255 255
-0.074848 0.019093 0.000000 255 255 255 255
-0.074205 0.020636 0.000000 255 255 255 255
-0.074467 0.020636 0.000000 255 255 255 255
-0.073480 0.020636 0.000000 255 255 255 255
-0.072384 0.020636 0.000000 255 255 255 255
-0.071011 0.020636 0.000000 255 255 255 255
-0.069452 0.020636 0.000000 255 255 255 255
-0.067801 0.020636 0.000000 255 255 255 255
-0.066149 0.020636 0.000000 255 255 255 255
-0.064591 0.020636 0.000000 255 255 255 255
-0.063217 0.020636 0.000000 255 255 255 255
-0.062122 0.020636 0.000000 255 255 255 255
-0.061396 0.020636 0.000000 255 255 255 255
-0.061134 0.020636 0.000000 255 255 255 255
-0.061592 0.019110 0.000000 255 255 255 255
0.020367 0.017147 0.000000 255 255 255 255
-0.020244 0.017147 0.000000 255 255 255 255
-0.062013 0.017568 0.000000 255 255 255 255
-0.075197 0.017538 0.000000 255 255 255 255
0.063609 0.010096 0.000000 255 255 255 255
-0.062397 0.016011 0.000000 255 255 255 255
-0.075515 0.015971 0.000000 255 255 255 255
0.022211 0.014419 0.000000 255 255 255 255
-0.022088 0.014419 0.000000 255 255 255 255
-0.062742 0.014440 0.000000 255 255 255 255
-0.075801 0.014393 0.000000 255 255 255 255
-0.063049 0.012854 0.000000 255 255 255 255
0.023698 0.011458 0.000000 255 255 255 255
-0.023575 0.011458 0.000000 255 255 255 255
-0.076055 0.012803 0.000000 255 255 255 255
-0.063317 0.011254 0.000000 255 255 255 255
-0.076277 0.011204 0.000000 255 255 255 255
0.077021 0.001401 0.000000 255 255 255 255
0.024798 0.008293 0.000000 255 255 255 255
-0.024675 0.008293 0.000000 255 255 255 255
-0.063545 0.009641 0.000000 255 255 255 255
-0.076465 0.009594 0.000000 255 255 255 255
0.064194 0.001401 0.000000 255 255 255 255
-0.063733 0.008016 0.000000 255 255 255 255
-0.076620 0.007973 0.000000 255 255 255 255
0.025480 0.004956 0.000000 255 255 255 255
-0.025357 0.004956 0.000000 255 255 255 255
-0.063880 0.006379 0.000000 255 255 255 255
-0.076741 0.006344 0.000000 255 255 255 255
-0.063986 0.004730 0.000000 255 255 255 255
-0.076828 0.004705 0.000000 255 255 255 255
0.025715 0.001478 0.000000 255 255 255 255
-0.025592 0.001478 0.000000 255 255 255 255
-0.064050 0.003071 0.000000 255 255 255 255
-0.076880 0.003057 0.000000 255 255 255 255
-0.064071 0.001401 0.000000 255 255 255 255
-0.076898 0.001401 0.000000 255 255 255 255
-0.025357 -0.002001 0.000000 255 255 255 255
0.025480 -0.002001 0.000000 255 255 255 255
-0.076195 -0.009033 0.000000 255 255 255 255
-0.063485 -0.007296 0.000000 255 255 255 255
0.063609 -0.007296 0.000000 255 255 255 255
0.076318 -0.009033 0.000000 255 255 255 255
-0.024675 -0.005338 0.000000 255 255 255 255
0.024798 -0.005338 0.000000 255 255 255 255
-0.023575 -0.008503 0.000000 255 255 255 255
0.023698 -0.008503 0.000000 255 255 255 255
-0.061779 -0.015639 0.000000 255 255 255 255
0.061902 -0.015639 0.000000 255 255 255 255
-0.022088 -0.011464 0.000000 255 255 255 255
0.022211 -0.011464 0.000000 255 255 255 255
0.074270 -0.019038 0.000000 255 255 255 255
-0.074147 -0.019038 0.000000 255 255 255 255
-0.020244 -0.014192 0.000000 255 255 255 255
0.020367 -0.014192 0.000000 255 255 255 255
0.018198 -0.016655 0.000000 255 255 255 255
-0.018075 -0.016655 0.000000 255 255 255 255
-0.059028 -0.023550 0.000000 255 255 255 255
0.059152 -0.023550 0.000000 255 255 255 255
0.015734 -0.018824 0.000000 255 255 255 255
-0.015611 -0.018824 0.000000 255 255 255 255
0.013006 -0.020667 0.000000 255 255 255 255
-0.012883 -0.020667 0.000000 255 255 255 255
0.070969 -0.028525 0.000000 255 255 255 255
-0.070846 -0.028525 0.000000 255 255 255 255
0.010044 -0.022154 0.000000 255 255 255 255
-0.009921 -0.022154 0.000000 255 255 255 255
0.006879 -0.023254 0.000000 255 255 255 255
-0.006756 -0.023254 0.000000 255 255 255 255
0.003541 -0.023936 0.000000 255 255 255 255
-0.003418 -0.023936 0.000000 255 255 255 255
-0.055310 -0.030954 0.000000 255 255 255 255
0.055434 -0.030954 0.000000 255 255 255 255
0.000061 -0.024170 0.000000 255 255 255 255
-0.066384 -0.037402 0.000000 255 255 255 255
0.066507 -0.037402 0.000000 255 255 255 255
-0.050701 -0.037773 0.000000 255 255 255 255
0.050826 -0.037773 0.000000 255 255 255 255
-0.060854 -0.045576 0.000000 255 255 255 255
0.060977 -0.045576 0.000000 255 255 255 255
-0.045278 -0.043932 0.000000 255 255 255 255
0.045403 -0.043932 0.000000 255 255 255 255
-0.039118 -0.049353 0.000000 255 255 255 255
0.039243 -0.049353 0.000000 255 255 255 255
-0.054346 -0.052957 0.000000 255 255 255 255
0.054469 -0.052957 0.000000 255 255 255 255
-0.032297 -0.053961 0.000000 255 255 255 255
0.032422 -0.053960 0.000000 255 255 255 255
-0.046954 -0.059454 0.000000 255 255 255 255
0.047077 -0.059454 0.000000 255 255 255 255
0.025017 -0.057677 0.000000 255 255 255 255
-0.024891 -0.057677 0.000000 255 255 255 255
0.017104 -0.060427 0.000000 255 255 255 255
-0.016979 -0.060427 0.000000 255 255 255 255
-0.038769 -0.064974 0.000000 255 255 255 255
0.038892 -0.064974 0.000000 255 255 255 255
0.008760 -0.062133 0.000000 255 255 255 255
-0.008636 -0.062133 0.000000 255 255 255 255
0.000061 -0.062719 0.000000 255 255 255 255
-0.029883 -0.069427 0.000000 255 255 255 255
0.030006 -0.069427 0.000000 255 255 255 255
-0.020388 -0.072721 0.000000 255 255 255 255
0.020511 -0.072721 0.000000 255 255 255 255
-0.010375 -0.074764 0.000000 255 255 255 255
0.010498 -0.074764 0.000000 255 255 255 255
0.000061 -0.075466 0.000000 255 255 255 255
3 0 1 2
3 3 4 5
3 6 4 3
3 7 4 6
3 7 8 4
3 9 8 7
3 10 8 9
3 11 8 10
3 11 12 8
3 13 12 11
3 14 12 13
3 14 15 12
3 16 15 14
3 17 15 16
3 18 15 17
3 18 19 15
3 19 20 15
3 20 21 15
3 1 22 18
3 22 19 18
3 1 23 22
3 1 24 23
3 25 21 20
3 1 26 24
3 0 27 1
3 27 28 1
3 28 29 1
3 29 30 1
3 30 31 1
3 31 26 1
3 32 21 25
3 32 33 21
3 34 33 32
3 0 35 27
3 0 36 35
3 37 33 34
3 37 38 33
3 0 39 36
3 0 40 39
3 0 41 40
3 0 42 41
3 43 38 37
3 0 44 42
3 0 45 44
3 0 46 45
3 43 47 38
3 0 48 46
3 49 47 43
3 0 50 48
3 0 51 50
3 0 52 51
3 0 53 52
3 54 47 49
3 54 55 47
3 0 56 53
3 57 55 54
3 57 58 55
3 59 60 61
3 59 62 60
3 63 62 59
3 64 58 57
3 63 65 62
3 66 65 63
3 66 67 65
3 68 67 66
3 68 69 67
3 70 69 68
3 64 71 58
3 70 72 69
3 73 72 70
3 74 75 76
3 74 77 75
3 74 78 77
3 74 79 78
3 74 80 79
3 74 81 80
3 74 82 81
3 74 83 82
3 74 84 83
3 74 85 84
3 74 86 85
3 74 87 86
3 74 88 87
3 73 89 72
3 90 89 73
3 74 91 88
3 92 91 74
3 93 71 64
3 92 94 91
3 95 94 92
3 90 96 89
3 97 96 90
3 95 98 94
3 99 98 95
3 99 100 98
3 97 101 96
3 102 101 97
3 103 100 99
3 103 104 100
3 105 104 103
3 93 106 71
3 102 107 101
3 108 107 102
3 105 109 104
3 110 109 105
3 111 106 93
3 110 112 109
3 113 112 110
3 108 114 107
3 115 114 108
3 113 116 112
3 117 116 113
3 117 118 116
3 119 118 117
3 115 120 114
3 121 120 115
3 119 122 118
3 123 122 119
3 123 124 122
3 125 124 123
3 126 120 121
3 126 127 120
3 128 124 125
3 128 129 124
3 130 106 111
3 130 131 106
3 132 127 126
3 132 133 127
3 134 133 132
3 134 135 133
3 128 136 129
3 137 131 130
3 138 135 134
3 138 139 135
3 137 140 131
3 141 136 128
3 142 139 138
3 142 143 139
3 142 144 143
3 145 144 142
3 141 146 136
3 147 140 137
3 145 148 144
3 149 148 145
3 149 150 148
3 151 150 149
3 147 152 140
3 153 146 141
3 151 154 150
3 155 154 151
3 155 156 154
3 157 156 155
3 157 158 156
3 159 158 157
3 153 160 146
3 161 152 147
3 159 162 158
3 163 160 153
3 161 164 152
3 163 165 160
3 166 164 161
3 167 165 163
3 166 168 164
3 167 169 165
3 170 168 166
3 167 171 169
3 172 168 170
3 173 171 167
3 172 174 168
3 173 175 171
3 176 174 172
3 177 175 173
3 176 178 174
3 179 178 176
3 177 180 175
3 181 178 179
3 177 182 180
3 183 182 177
3 181 184 178
3 185 184 181
3 183 186 182
3 187 184 185
3 183 187 186
3 183 184 187
3 188 184 183
3 188 189 184
3 190 189 188
3 190 191 189
3 192 191 190
3 192 193 191
3 194 193 192