Вероятно, който се е занимавал с моделиране на 3д обекти, под някаква форма се е сблъсквал с програмата Google Sketch Up. Личното ми мнение е, че това е една страхотна програма, изключително лека (зарежда със скоростта на Notepad), а в същото време дава доста големи възможности за свободно моделиране на всевъзможни форми и като цяло поне за мен за създаването на малки по размер 3д обекти и дизайни, както и за концептуални модели, програмата е наистина безценна.
Още повече се запалих по тази програма преди няколко години, когато разбрах, че за Sketch Up си има една цяла общност от ентусиасти (Sketchucation.com), които пишат и публикуват безплатни плъгини (направени за собствени нужди или по поръчка на някой пишещ във форума), които плъгини добавени към програмата вече могат да я направят наистина мощно средство за лесно създаване на модели за дизайн и архитектура например.
Така след като известно време ползвах различни плъгини към програмата, в един момент реших и аз да се пробвам да се науча и да пиша такива. И това се оказа далеч не толкова трудна задача – макар и никога дотогава да не бях и чувал за Ruby, в интернет има изключително удобна и подробна документация на Sketch Up Ruby API и след прочитането на една малка книжка за основите на езика, аз вече можех спокойно да пиша първите си плъгини.
Цялата идея е да се напише един файл с разширение .rb, който да се сложи в инсталационната директория на програмата в папка Plugins. При зареждане на Sketch Up, програмата компилира всички файлове в папка Plugins, и те вече стават активни в текущо отворения прозорец на Sketch Up. Тук е момента и да кажа, че ако си свалите стотина Plugin-a в папката, то вече Sketch Up далеч няма да зарежда вече със скоростта на Notepad, ами по скоро ще се доближи до тази на 3DSMax, което както и да го погледнем не е на добре. 🙂 Затова излишните Plugin-и по-добре ги скрийте в една директория да речем HiddenPlugins, и когато ви потрябват си ги извадете от там.
До към септември 2012 си бях написал десетина плъгина за лични нужди, свързани с някои от архитектурните проекти, върху които работех и честно казано от тогава не ми остава време сядам да се занимавам с това (странно защо този времеви период съвпада със започването ми като студент в академията на Телерик 🙂 ). И все пак въпреки, че имах желание да пипна малко въпросните плъгини, за да бъдат малко по-подходящи за гледане от други хора :), реших да представя поне един от тях, който позволява движението в моделното пространство на Sketch Up да бъде като това в познатите ни компютърни игри като CounterStrike например. Поне според мен този plugin значително улеснява придвижването, особено в по-големи модели, където “зуумванете” и “орбитирането” (стандартните Tool-ове в Sketch Up за навигиране), просто не работят както трябва и навигирането става изключително затруднено.
Ето и линк към моя tool: DPY-Camera-24-09-2012.rar
За да го инсталирате, както казах и по-горе, просто слагате .rar-файла в директорията Plugins на SketchUp и го екстрактвате. В самия архив освен .rb файла има една папка, съдържаща картинки използвани от моят tool, както и Win32API.so файл, който е необходим, тъй като в скрипта съм използвал външни за Ruby функции, за да мога да манипулирам успешно мишката под Windows, тъй като за правилната работа на този tool е необходимо да мога да местя курсора на определена позиция.
Ще започна първо с обяснение за хората, които искат да използват моят tool, но не държат да знаят точно как работи кодът му. След като сте инсталирали плъгина, отваряте Sketch Up, а ако е отворен от преди го рестартирайте (тъй като плъгина се компилира и зарежда като функциониращ tool, при стартиране на програмата и няма да се зареди ако не рестартирате Sketch Up). Намерете иконката в Toolbar-а, както е показано на картиката по-долу.
DPY-Camera се стартира при цъкане на иконката в Toolbar-a. Изключването на tool-a, става посредством натискането на spacebar (което активира tool-a за селекция в Sketch Up), или при натискането на друг бутон, който активира съответен tool (например М за move). Най-долу в message bar-a се изписват помощни съобщения по време на използването на tool-a, указващи клавишите за навигация, стойност на скоростта и др. Скоростта се задава в m/s като ако искате да се движите по-бързо или по-бавно просто пишете цифрено новата стойност и натискате Enter. Това е удобно тъй като в зависимост от размерите на обекта, който искате да огледате, може да се налага да се приближавате детайлно близо(примерно при моделиране дизайна на една мебел), или пък да се придвижвате с много голяма скорост (ако моделирате един градски пейзаж да речем).
След като сте стартирали и направили някакво движение ще забележите, че долу при съобщенията се появява един надпис “Click for MouseCorrection!”. Това е поради един бъг, който не успях да намеря по-умен начин да корегирам, свързан с малко отместване на данните за позицията на мишка от Win32API и от SketchUpRubyAPI. Просто цъкнете веднъж с мишката и ще можете да използвате пълната функционалност на tool-a от тук нататък. Ако не цъкнете – ами отново ще може да се придвижвате безпроблемно, но няма да можете да използвате бонус опцията наречена “Gun Mode” :), при която в последствие ще можете да си включите един мерник и при цъкане да “гръмнете” (или в случая да изтриете от модела) обекта който ви е на мушката (edge, face, group, component или каквото ви се изпречи насреща 🙂 ).
След като веднъж сте кликнали с мишката ще видите, че долу в ляво надписа “MouseCorrection” е изчезнал и на негово място имате опция “GunMode On/Off”. GunMode се включва и изключва с Escape, както е и описано в message bar-a, и при включен GunMode мерникът става кръстче с точка по средата (ако е изключен стои само точката).
Когато цъкнете при включен GunMode до курсора се изписва “BOOM!” и се изтрива обекта, който е на мушката, така че бъдете внимателни при включен мерник 🙂 (не че не можете с undo да си върнете изтритото, но все пак).
В общи линии това е по обяснението за използването на Tool-a. Надявам се да ви харесва и да ви бъде полезен. Имах желанието (но не и времето) за добавяне на повече функционалност – не само можеш да триеш при кликане с мишката ами примерно да рисуваш нещо върху модела или някаква друга функционално каквато може да се сети някой. Ако някой има идеи за подобрение нека пише или нека направо работи върху кода, който ще обясня накратко по-надолу.
Като начало каква е идеята на самия код, за да работи в конкретния случай. Движението със стрелките е просто и ясно – при задържане на някоя стрелките камерата започва да се движи с необходимата скорост в съответната посока. Как работи въртенето на камерата? Ами също не толкова сложно – при преместване на мишката tool-a отчита новата позиция на мишката, запазва мястото на камерата, премества фокусната точка върху някоя точка по лъча получен при свързването на позицията на камерата и новата точка на мишката. След като камерата е преместена нашият tool връща мястото на мишката в първоначалната позиция. Така мишката винаги стои по средата на екрана, във фокуса на камерата и съвпадайки с посоката на движение при задържана стрелка напред.
Поглеждайки в Sketch Up Ruby API можем да видим, че на пръв поглед един tool в скеч ъп има контрол над всичките ни необходими команди за прихващане на събития свързани с мишката и клавиатурата. На втори и трети поглед, почвайки да пишем кода, се сблъскваме с няколко проблема, които са свързани както с непълнотии в API-то, така и с бъгове в някои от съществуващите опции.
На първо време нека кажа какво трябва да се направи, за да си дефинираш един tool в Sketch Up. Ами всъщност е доста просто – просто си правиш един нов клас и него започваш да го пълниш с методите описани в документацията, необходими за да бъде разпозната в последствие от Sketch Up създадената инстанция на този клас като tool, а не като някакъв друг произволен клас. Важен в случая е метода activate, който активира tool-a при създаване на инстанцията на класа. В този метод се случват и началните действия, необходими за работата на нашия tool. Ето я и конкретната имплементация на този метод:
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | def activate camera = Sketchup.active_model.active_view.camera newTarget = Geom::Point3d.linear_combination 1.0, camera.eye, 1.0, camera.zaxis.to_a camera.set camera.eye, newTarget, [0,0,1] @@mouseDouble = false @@boom = false @@eraser = false @@mouseCorrected = false @@vk_up = false @@vk_down = false @@vk_left = false @@vk_right = false @firstPress = true @@animate = true @c = Sketchup.active_model.active_view.center @corX = 0 @corY = 0 @@v = 6/0.0254 @msg = "Use arrow keys and mouse to navigate! Velocity = " + (@@v*0.0254).to_s + " m/s. Change it by typing a desired velocity and pressing Enter." Sketchup::set_status_text(@msg) setCursorPos = Win32API.new("user32", "SetCursorPos", ['I', 'I'], 'V') setCursorPos.Call(@c[0]+@corX,@c[1]+@corY) end |
Тук е и момента да помоля за извинения читателя на тази статия за странното форматиране на кода. Истината е, че в Notepad++ индентирането си изглежда нормално, но пействайки го тук става някакво разминаване, което трябва да оправям ръчно. В момента, в който ми се отвори време, ще се опитам да го оправя, но в случай, че на някой му е неприятно да го гледа от тук, би могъл да отвори файла DPY_CAMERA_24_09_2012.rb, който е в горния архив.
В методa activate си инициализирам началните стойности на глобалните и неглобалните променливи на класа. В самия му край (ред 96 и 97) може да видите и задаването на началното преместване на курсора в центъра на екрана. Тук е и първия проблем със Sketch Up Ruby API, с който трябваше да се сблъсквам – няма метод който да ми позволява преместването на мишката на определена позиция. След извесно търсене в нета, намерих решението на този проблем с външен метод от Win32API, който първо го дефинирам и после го извиквам. Това е един от най-малките проблеми, с които трябваше да се сблъскам, пишейки този плъгин. 🙂
Освен метода activate tool-a може да съдържа още един куп методи, които кръстени по определен начин, описан в Sketch Up Ruby API, биват разпознавани в последствие от Sketch Up и биват използвани за конкретни цели. Такива са методите OnMouseMove, OnKeyDown и други. Няма да ги описвам подробно. Който иска може да си прочете за тях в документацията, в която има и доста подходящи примери.
Накратко ще спомена и другите проблеми, с които се сблъсках. Метода, който използва Sketch Up за отчитане на координатите на текущата позиция на мишката се различава резултатите за координатите от външните методи, които ползвам от Win32API. Това наложи да използвам метод от Win32API и за взимането на координатите, за да няма разминавания. Това се случва в метода onMouseMove:
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | def onMouseMove(flags, x, y, view) getCursorPos = Win32API.new("user32", "GetCursorPos", ['P'], 'V') lpPoint = " " * 8 # store two LONGs getCursorPos.Call(lpPoint) p, q = lpPoint.unpack("LL") # get the actual values ray = view.pickray p-@corX, q-@corY status = ray[1].samedirection? [0,0,1] if(!status) view.camera.set ray[0], ray[1], [0,0,1] end setCursorPos = Win32API.new("user32", "SetCursorPos", ['I', 'I'], 'V') setCursorPos.Call(@c[0]+@corX,@c[1]+@corY) end |
Дотук добре. Истинският проблем обаче се появява, в момента, в който решавам, че искам да мога да включвам един мерник и с цъкане на мишката да “стрелям” и да изтривам обектите пред мерника. В Sketch Up Ruby API има готови класове и методи, с които мога да разбера кой е обекта под мишката ми и да го селектирам и съответно променя или направо изтрия. Това е чудесно, но с наличните разминавания на координатите на позициита на курсора, би било неприятно мерника ми да е нарисуван и да сочи към един обект, а аз като “стрелям” да изтрия някой съседен на него такъв. След като търсих начин да успея да унифицирам координатите от Sketch Up Ruby API и Win32API, за съжаление най-умното, което успях измисля е да поискам от потребителя на моя tool да направи просто един клик с мишката и отчитайки разликата от координатите на двете API-та, аз оттук нататък да използвам две променливи за корекция по x и корекция по y, като по този начин съм сигурен че мерника ми ще е напълно точен :). Ако някой успее да измисли по-добро решение на този проблем, ще се радвам да го сподели.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | def onLButtonDown(flags, x, y, view) if(!@@mouseCorrected) @@mouseCorrected = true @corX = @c[0] - x @corY = @c[1] - y end if(@@eraser and @@mouseCorrected) @@boom = true ph = view.pick_helper ph.do_pick x,y best = ph.best_picked if(!best.deleted?) then best.erase! end end =begin ### Dictionaries and Attributes ### if(!@@eraser and @@mouseCorrected) ph = view.pick_helper ph.do_pick x,y best = ph.best_picked inputpoint = view.inputpoint x, y if(!best.deleted?) best.set_attribute best.typename, "test", inputpoint.position best.attribute_dictionaries.each { |dict| print="" dict.each { |key,value| print += dict.name.to_s + " --> " + key.to_s + " = " + value.to_s + "\n" } UI.messagebox(print) } end end =end end #end of LButtonDown |
Големият закоментиран код в метода onLButtonDown (от ред 152 до ред 169), не е оставен там случайно. Тук съм си правил ескперименти с различни други функционалности, които биха могли да се добавят при кликане с мишката, освен сегашната функционалност за стреляне. Ако някои има идеи за реализация на рисуване с мишката или каквото и да било друго, може би тук е мястото, където трябва да добави малко код и да добави необходимата според него допълнителна функционалност на tool-а.
Последният проблем, с който се сблъсках, беше свързан с един бъг в Sketch Up Ruby API, свързан със събитието задържан клавиш. В документацията е записано, че при onKeyDown аз мога да имам информация за това дали клавиша е натиснат еднократно или е задържан. Това е вярно, но за съжаление работи само под Mac. Под Windows има някакъв бъг и тази опция просто не работи. Затова, вече решил проблема с ротацията на камерата, аз се сблъсках неочаквано и с проблем с нейното транслиране, тъй като искам при задържан бутон (стрелка) камерата да се транслира плавно с определена скорост в дадена посока. За да реализирам това успешно използвам комбинация от методите onKeyDown и onKeyUp, които ми дават информация кога някоя стрелка е натисната и кога е пусната. Тази информация съответно я пазя в една булева променлива за всяка от стрелките като тези променливи ги правя глобални за класа на моя tool. Всичко, което остава да направя, е да направя анимация на транслирането на камерата в зависимост от състоянието на тези булеви променливи. Анимация в Sketch Up се прави като се дефинира един допълнителен клас за анимацията. Този клас трябва да има един метод на име nextFrame, чието име мисля че достатъчно ясно говори за какво служи :). Ето и конкретната имплементация на класа за анимацията:
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | class Animation def initialize @@DPY = DPYmoveCAMERAtool.new @camera = Sketchup.active_model.active_view.camera @time = Sketchup.active_model.active_view.average_refresh_time * 10 @v = @@DPY.velocity @msg = "" @newEye = Geom::Point3d.new @newTarget = Geom::Point3d.new end def nextFrame(view) @camera = view.camera @time = view.average_refresh_time * 10 @v = @@DPY.velocity if (@@DPY.vk_up) @newEye = Geom::Point3d.linear_combination 1.0, @camera.eye, @v*@time, @camera.zaxis.to_a @newTarget = Geom::Point3d.linear_combination 1.0, @camera.target, @v*@time, @camera.zaxis.to_a view.camera.set @newEye, @newTarget, [0,0,1] end if (@@DPY.vk_down) @newEye = Geom::Point3d.linear_combination 1.0, @camera.eye, -@v*@time, @camera.zaxis.to_a @newTarget = Geom::Point3d.linear_combination 1.0, @camera.target, -@v*@time, @camera.zaxis.to_a view.camera.set @newEye, @newTarget, [0,0,1] end if (@@DPY.vk_left) @newEye = Geom::Point3d.linear_combination 1.0, @camera.eye, -@v*@time, @camera.xaxis.to_a @newTarget = Geom::Point3d.linear_combination 1.0, @camera.target, -@v*@time, @camera.xaxis.to_a view.camera.set @newEye, @newTarget, [0,0,1] end if (@@DPY.vk_right) @newEye = Geom::Point3d.linear_combination 1.0, @camera.eye, @v*@time, @camera.xaxis.to_a @newTarget = Geom::Point3d.linear_combination 1.0, @camera.target, @v*@time, @camera.xaxis.to_a view.camera.set @newEye, @newTarget, [0,0,1] end @msg = "Velocity = " + (@v*0.0254).to_s + " m/s. Position in space --> " + view.camera.eye[0].to_s + " " + view.camera.eye[1].to_s + " " + view.camera.eye[2].to_s if(!@@DPY.mouseCorrected) then @msg = @msg + ". Click for MouseCorrection!" end if(@@DPY.mouseCorrected) @msg = @msg + ". Esc for GunMode On/Off: " if(@@DPY.eraser) then @msg = @msg + "On" end if(!@@DPY.eraser) then @msg = @msg + "Off" end end if(!@@DPY.animate) @msg = "" end Sketchup::set_status_text(@msg) view.show_frame return @@DPY.animate end end |
Самата анимация се стартира при създаване на инстанция на класа Animation, което аз правя при първото извикване на метода onKeyDown от класа на моя tool:
197 198 199 200 201 202 203 204 205 206 207 208 209 | def onKeyDown(key, repeat, flags, view) if(@firstPress) @firstPress = false Sketchup.active_model.active_view.animation = Animation.new end if (key == VK_UP) then @@vk_up = true end if (key == VK_DOWN) then @@vk_down = true end if (key == VK_RIGHT) then @@vk_right = true end if (key == VK_LEFT) then @@vk_left = true end end |
Кореспонденцията между двата класа я правя посредством глобалните променливи на класа на моя tool (това са тези променливи, започващи с двете кльомби :)).
И така имайки вече цялата функционално – tool + animation, можем да заредим нашия tool в toolbar-a и при кликане да го стартираме:
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | ######Creating new toolbar item toolbar = UI::Toolbar.new "DPY_CAMERA" ######Adding new command to the toolbar item DPY_CAMERA = UI::Command.new("DPY_CAMERA") { Sketchup.active_model.start_operation 'DPY_CAMERA', true Sketchup.active_model.select_tool DPYmoveCAMERAtool.new Sketchup.active_model.commit_operation } DPY_CAMERA.small_icon = File.join("DPY_CAMERA", "DPY_CAMERA_small.jpg") DPY_CAMERA.large_icon = File.join("DPY_CAMERA", "DPY_CAMERA_large.jpg") toolbar = toolbar.add_item DPY_CAMERA toolbar.show |
И това е всичко! Събирайки целия код в едно получаваме финалния резултат:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 | require 'Win32API' class Animation def initialize @@DPY = DPYmoveCAMERAtool.new @camera = Sketchup.active_model.active_view.camera @time = Sketchup.active_model.active_view.average_refresh_time * 10 @v = @@DPY.velocity @msg = "" @newEye = Geom::Point3d.new @newTarget = Geom::Point3d.new end def nextFrame(view) @camera = view.camera @time = view.average_refresh_time * 10 @v = @@DPY.velocity if (@@DPY.vk_up) @newEye = Geom::Point3d.linear_combination 1.0, @camera.eye, @v*@time, @camera.zaxis.to_a @newTarget = Geom::Point3d.linear_combination 1.0, @camera.target, @v*@time, @camera.zaxis.to_a view.camera.set @newEye, @newTarget, [0,0,1] end if (@@DPY.vk_down) @newEye = Geom::Point3d.linear_combination 1.0, @camera.eye, -@v*@time, @camera.zaxis.to_a @newTarget = Geom::Point3d.linear_combination 1.0, @camera.target, -@v*@time, @camera.zaxis.to_a view.camera.set @newEye, @newTarget, [0,0,1] end if (@@DPY.vk_left) @newEye = Geom::Point3d.linear_combination 1.0, @camera.eye, -@v*@time, @camera.xaxis.to_a @newTarget = Geom::Point3d.linear_combination 1.0, @camera.target, -@v*@time, @camera.xaxis.to_a view.camera.set @newEye, @newTarget, [0,0,1] end if (@@DPY.vk_right) @newEye = Geom::Point3d.linear_combination 1.0, @camera.eye, @v*@time, @camera.xaxis.to_a @newTarget = Geom::Point3d.linear_combination 1.0, @camera.target, @v*@time, @camera.xaxis.to_a view.camera.set @newEye, @newTarget, [0,0,1] end @msg = "Velocity = " + (@v*0.0254).to_s + " m/s. Position in space --> " + view.camera.eye[0].to_s + " " + view.camera.eye[1].to_s + " " + view.camera.eye[2].to_s if(!@@DPY.mouseCorrected) then @msg = @msg + ". Click for MouseCorrection!" end if(@@DPY.mouseCorrected) @msg = @msg + ". Esc for GunMode On/Off: " if(@@DPY.eraser) then @msg = @msg + "On" end if(!@@DPY.eraser) then @msg = @msg + "Off" end end if(!@@DPY.animate) @msg = "" end Sketchup::set_status_text(@msg) view.show_frame return @@DPY.animate end end class DPYmoveCAMERAtool def initialize cursorPath2 = Sketchup.find_support_file ("DpyCameraCursor2.png", "Plugins/DPY_CAMERA/") @@cursor2 = UI.create_cursor(cursorPath2, 5, 5) #cursorPath1 = Sketchup.find_support_file ("DpyCameraCursor1.png", "Plugins/DPY_CAMERA/") #@@cursor1 = UI.create_cursor(cursorPath1, 5, 5) end def onSetCursor UI.set_cursor(@@cursor2) end def activate camera = Sketchup.active_model.active_view.camera newTarget = Geom::Point3d.linear_combination 1.0, camera.eye, 1.0, camera.zaxis.to_a camera.set camera.eye, newTarget, [0,0,1] @@mouseDouble = false @@boom = false @@eraser = false @@mouseCorrected = false @@vk_up = false @@vk_down = false @@vk_left = false @@vk_right = false @firstPress = true @@animate = true @c = Sketchup.active_model.active_view.center @corX = 0 @corY = 0 @@v = 6/0.0254 @msg = "Use arrow keys and mouse to navigate! Velocity = " + (@@v*0.0254).to_s + " m/s. Change it by typing a desired velocity and pressing Enter." Sketchup::set_status_text(@msg) setCursorPos = Win32API.new("user32", "SetCursorPos", ['I', 'I'], 'V') setCursorPos.Call(@c[0]+@corX,@c[1]+@corY) end def draw(view) if(@@eraser and @@mouseCorrected) view.drawing_color = "red" d = 5 l = 25 view.draw2d GL_LINES, [@c[0],@c[1] - d,0],[@c[0],@c[1] - l,0] , [@c[0],@c[1] + d,0],[@c[0],@c[1] + l,0] , [@c[0] - d,@c[1],0],[@c[0] - l,@c[1],0] , [@c[0] + d,@c[1],0],[@c[0] + l,@c[1],0] if(@@boom) then status = view.draw_text [@c[0] + d,@c[1] + d,0], "BOOM!" end if(@@mouseDouble = true) @@boom = false @@mouseDouble = false end end end def deactivate(view) @@animate = false end def onCancel(reason, view) @@eraser = !@@eraser end def onUserText(text, view) if(text.to_f) then @@v = text.to_f/0.0254 end end def onLButtonDoubleClick(flags, x, y, view) if(@@eraser and @@mouseCorrected) @@mouseDouble = true @@boom = true ph = view.pick_helper ph.do_pick x,y best = ph.best_picked if(!best.deleted?) then best.erase! end end end def onLButtonDown(flags, x, y, view) if(!@@mouseCorrected) @@mouseCorrected = true @corX = @c[0] - x @corY = @c[1] - y end if(@@eraser and @@mouseCorrected) @@boom = true ph = view.pick_helper ph.do_pick x,y best = ph.best_picked if(!best.deleted?) then best.erase! end end =begin ### Dictionaries and Attributes ### if(!@@eraser and @@mouseCorrected) ph = view.pick_helper ph.do_pick x,y best = ph.best_picked inputpoint = view.inputpoint x, y if(!best.deleted?) best.set_attribute best.typename, "test", inputpoint.position best.attribute_dictionaries.each { |dict| print="" dict.each { |key,value| print += dict.name.to_s + " --> " + key.to_s + " = " + value.to_s + "\n" } UI.messagebox(print) } end end =end end #end of LButtonDown def onLButtonUp(flags, x, y, view) @@boom = false end def onMouseMove(flags, x, y, view) getCursorPos = Win32API.new("user32", "GetCursorPos", ['P'], 'V') lpPoint = " " * 8 # store two LONGs getCursorPos.Call(lpPoint) p, q = lpPoint.unpack("LL") # get the actual values ray = view.pickray p-@corX, q-@corY status = ray[1].samedirection? [0,0,1] if(!status) view.camera.set ray[0], ray[1], [0,0,1] end setCursorPos = Win32API.new("user32", "SetCursorPos", ['I', 'I'], 'V') setCursorPos.Call(@c[0]+@corX,@c[1]+@corY) end def onKeyDown(key, repeat, flags, view) if(@firstPress) @firstPress = false Sketchup.active_model.active_view.animation = Animation.new end if (key == VK_UP) then @@vk_up = true end if (key == VK_DOWN) then @@vk_down = true end if (key == VK_RIGHT) then @@vk_right = true end if (key == VK_LEFT) then @@vk_left = true end end def onKeyUp(key, repeat, flags, view) if (key == VK_UP) then @@vk_up = false end if (key == VK_DOWN) then @@vk_down = false end if (key == VK_LEFT) then @@vk_left = false end if (key == VK_RIGHT) then @@vk_right = false end end def animate @@animate end def vk_up @@vk_up end def vk_down @@vk_down end def vk_left @@vk_left end def vk_right @@vk_right end def velocity @@v end def mouseCorrected @@mouseCorrected end def eraser @@eraser end end # end class DPYmoveCAMERAtool definition ######Dobawqne na toolbar toolbar = UI::Toolbar.new "DPY_CAMERA" ######Dobawqne na komanda tetrahedron kam toolbara DPY_CAMERA = UI::Command.new("DPY_CAMERA") { Sketchup.active_model.start_operation 'DPY_CAMERA', true Sketchup.active_model.select_tool DPYmoveCAMERAtool.new Sketchup.active_model.commit_operation } DPY_CAMERA.small_icon = File.join("DPY_CAMERA", "DPY_CAMERA_small.jpg") DPY_CAMERA.large_icon = File.join("DPY_CAMERA", "DPY_CAMERA_large.jpg") toolbar = toolbar.add_item DPY_CAMERA toolbar.show |
Leave a Reply