ccPropertiesTreeDelegate.cpp 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981
  1. //##########################################################################
  2. //# #
  3. //# CLOUDCOMPARE #
  4. //# #
  5. //# This program is free software; you can redistribute it and/or modify #
  6. //# it under the terms of the GNU General Public License as published by #
  7. //# the Free Software Foundation; version 2 or later of the License. #
  8. //# #
  9. //# This program is distributed in the hope that it will be useful, #
  10. //# but WITHOUT ANY WARRANTY; without even the implied warranty of #
  11. //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
  12. //# GNU General Public License for more details. #
  13. //# #
  14. //# COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI) #
  15. //# #
  16. //##########################################################################
  17. #include "ccPropertiesTreeDelegate.h"
  18. //Local
  19. #include "ccColorScaleEditorDlg.h"
  20. #include "ccColorScaleSelector.h"
  21. #include "mainwindow.h"
  22. #include "matrixDisplayDlg.h"
  23. #include "sfEditDlg.h"
  24. //qCC_glWindow
  25. #include <ccGLWindowInterface.h>
  26. #include <ccGuiParameters.h>
  27. //qCC_db
  28. #include <cc2DLabel.h>
  29. #include <cc2DViewportLabel.h>
  30. #include <cc2DViewportObject.h>
  31. #include <ccAdvancedTypes.h>
  32. #include <ccCameraSensor.h>
  33. #include <ccColorScalesManager.h>
  34. #include <ccCone.h>
  35. #include <ccFacet.h>
  36. #include <ccGBLSensor.h>
  37. #include <ccGenericPrimitive.h>
  38. #include <ccHObject.h>
  39. #include <ccHObjectCaster.h>
  40. #include <ccImage.h>
  41. #include <ccIndexedTransformationBuffer.h>
  42. #include <ccKdTree.h>
  43. #include <ccMaterialSet.h>
  44. #include <ccMesh.h>
  45. #include <ccOctree.h>
  46. #include <ccPlane.h>
  47. #include <ccPointCloud.h>
  48. #include <ccPolyline.h>
  49. #include <ccScalarField.h>
  50. #include <ccSensor.h>
  51. #include <ccSphere.h>
  52. #include <ccSubMesh.h>
  53. #include <ccCoordinateSystem.h>
  54. //Qt
  55. #include <QAbstractItemView>
  56. #include <QCheckBox>
  57. #include <QComboBox>
  58. #include <QHBoxLayout>
  59. #include <QLineEdit>
  60. #include <QLabel>
  61. #include <QLocale>
  62. #include <QPushButton>
  63. #include <QScrollBar>
  64. #include <QSlider>
  65. #include <QSpinBox>
  66. #include <QStandardItemModel>
  67. #include <QToolButton>
  68. #include <QEvent>
  69. //System
  70. #include <cassert>
  71. class FilterMouseWheelNoFocusEvent : public QObject
  72. {
  73. public:
  74. explicit FilterMouseWheelNoFocusEvent(QObject *parent)
  75. {
  76. }
  77. protected:
  78. bool eventFilter(QObject* o, QEvent* e) override
  79. {
  80. const QWidget* widget = dynamic_cast<QWidget*>(o);
  81. if (e->type() == QEvent::Wheel && widget && !widget->hasFocus())
  82. {
  83. e->ignore();
  84. return true;
  85. }
  86. return QObject::eventFilter(o, e);
  87. }
  88. };
  89. // Default 'None' string
  90. const char* ccPropertiesTreeDelegate::s_noneString = QT_TR_NOOP( "None" );
  91. // Default color sources string
  92. const char* ccPropertiesTreeDelegate::s_rgbColor = "RGB";
  93. const char* ccPropertiesTreeDelegate::s_sfColor = QT_TR_NOOP( "Scalar field" );
  94. // Other strings
  95. const char* ccPropertiesTreeDelegate::s_defaultPointSizeString = QT_TR_NOOP( "Default" );
  96. const char* ccPropertiesTreeDelegate::s_defaultPolyWidthSizeString = QT_TR_NOOP( "Default Width" );
  97. // Default separator colors
  98. constexpr const char* SEPARATOR_STYLESHEET = "QLabel { background-color : darkGray; color : white; }";
  99. //Shortcut to create a delegate item
  100. static QStandardItem* ITEM(const QString& name,
  101. Qt::ItemFlag additionalFlags = Qt::NoItemFlags,
  102. ccPropertiesTreeDelegate::CC_PROPERTY_ROLE role = ccPropertiesTreeDelegate::OBJECT_NO_PROPERTY)
  103. {
  104. QStandardItem* item = new QStandardItem(name);
  105. //flags
  106. item->setFlags(Qt::ItemIsEnabled | additionalFlags);
  107. //role (if any)
  108. if (role != ccPropertiesTreeDelegate::OBJECT_NO_PROPERTY)
  109. {
  110. item->setData(role);
  111. }
  112. return item;
  113. }
  114. //Shortcut to create a checkable delegate item
  115. static QStandardItem* CHECKABLE_ITEM(bool checkState, ccPropertiesTreeDelegate::CC_PROPERTY_ROLE role)
  116. {
  117. QStandardItem* item = ITEM("", Qt::ItemIsUserCheckable, role);
  118. //check state
  119. item->setCheckState(checkState ? Qt::Checked : Qt::Unchecked);
  120. return item;
  121. }
  122. //Shortcut to create a persistent editor item
  123. static QStandardItem* PERSISTENT_EDITOR(ccPropertiesTreeDelegate::CC_PROPERTY_ROLE role)
  124. {
  125. return ITEM(QString(), Qt::ItemIsEditable, role);
  126. }
  127. ccPropertiesTreeDelegate::ccPropertiesTreeDelegate(QStandardItemModel* model,
  128. QAbstractItemView* view,
  129. QObject *parent)
  130. : QStyledItemDelegate(parent)
  131. , m_currentObject(nullptr)
  132. , m_model(model)
  133. , m_view(view)
  134. , m_lastFocusItemRole(OBJECT_NO_PROPERTY)
  135. {
  136. assert(m_model && m_view);
  137. }
  138. ccPropertiesTreeDelegate::~ccPropertiesTreeDelegate()
  139. {
  140. unbind();
  141. }
  142. QSize ccPropertiesTreeDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
  143. {
  144. assert(m_model);
  145. QStandardItem* item = m_model->itemFromIndex(index);
  146. if (item && item->data().isValid())
  147. {
  148. switch (item->data().toInt())
  149. {
  150. case OBJECT_CURRENT_DISPLAY:
  151. case OBJECT_CURRENT_SCALAR_FIELD:
  152. case OBJECT_OCTREE_TYPE:
  153. case OBJECT_COLOR_RAMP_STEPS:
  154. case OBJECT_CLOUD_POINT_SIZE:
  155. return QSize(50, 24);
  156. case OBJECT_COLOR_SOURCE:
  157. case OBJECT_POLYLINE_WIDTH:
  158. case OBJECT_CURRENT_COLOR_RAMP:
  159. return QSize(70, 24);
  160. case OBJECT_CLOUD_SF_EDITOR:
  161. return QSize(250, 200);
  162. case OBJECT_SENSOR_MATRIX_EDITOR:
  163. case OBJECT_HISTORY_MATRIX_EDITOR:
  164. case OBJECT_GLTRANS_MATRIX_EDITOR:
  165. return QSize(250, 140);
  166. }
  167. }
  168. return QStyledItemDelegate::sizeHint(option, index);
  169. }
  170. void ccPropertiesTreeDelegate::unbind()
  171. {
  172. if (m_model)
  173. {
  174. m_model->disconnect(this);
  175. }
  176. }
  177. ccHObject* ccPropertiesTreeDelegate::getCurrentObject()
  178. {
  179. return m_currentObject;
  180. }
  181. void ccPropertiesTreeDelegate::fillModel(ccHObject* hObject)
  182. {
  183. if (!hObject)
  184. {
  185. return;
  186. }
  187. unbind();
  188. m_currentObject = hObject;
  189. //save current scroll position
  190. int scrollPos = (m_view && m_view->verticalScrollBar() ? m_view->verticalScrollBar()->value() : 0);
  191. if (m_model)
  192. {
  193. m_model->removeRows(0, m_model->rowCount());
  194. m_model->setColumnCount(2);
  195. m_model->setHeaderData(0, Qt::Horizontal, tr( "Property" ));
  196. m_model->setHeaderData(1, Qt::Horizontal, tr( "State/Value" ));
  197. }
  198. if (m_currentObject->isHierarchy())
  199. {
  200. if (!m_currentObject->isA(CC_TYPES::VIEWPORT_2D_LABEL)) //don't need to display this kind of info for viewport labels!
  201. {
  202. fillWithHObject(m_currentObject);
  203. }
  204. }
  205. if (m_currentObject->isA(CC_TYPES::COORDINATESYSTEM))
  206. {
  207. fillWithCoordinateSystem(ccHObjectCaster::ToCoordinateSystem(m_currentObject));
  208. }
  209. else if (m_currentObject->isKindOf(CC_TYPES::POINT_CLOUD))
  210. {
  211. fillWithPointCloud(ccHObjectCaster::ToGenericPointCloud(m_currentObject));
  212. }
  213. else if (m_currentObject->isKindOf(CC_TYPES::MESH))
  214. {
  215. fillWithMesh(ccHObjectCaster::ToGenericMesh(m_currentObject));
  216. if (m_currentObject->isKindOf(CC_TYPES::PRIMITIVE))
  217. {
  218. fillWithPrimitive(ccHObjectCaster::ToPrimitive(m_currentObject));
  219. }
  220. }
  221. else if (m_currentObject->isA(CC_TYPES::FACET))
  222. {
  223. fillWithFacet(ccHObjectCaster::ToFacet(m_currentObject));
  224. }
  225. else if (m_currentObject->isA(CC_TYPES::POLY_LINE))
  226. {
  227. fillWithPolyline(ccHObjectCaster::ToPolyline(m_currentObject));
  228. }
  229. else if (m_currentObject->isA(CC_TYPES::POINT_OCTREE))
  230. {
  231. fillWithPointOctree(ccHObjectCaster::ToOctree(m_currentObject));
  232. }
  233. else if (m_currentObject->isA(CC_TYPES::POINT_KDTREE))
  234. {
  235. fillWithPointKdTree(ccHObjectCaster::ToKdTree(m_currentObject));
  236. }
  237. else if (m_currentObject->isKindOf(CC_TYPES::IMAGE))
  238. {
  239. fillWithImage(ccHObjectCaster::ToImage(m_currentObject));
  240. }
  241. else if (m_currentObject->isA(CC_TYPES::LABEL_2D))
  242. {
  243. fillWithLabel(ccHObjectCaster::To2DLabel(m_currentObject));
  244. }
  245. else if (m_currentObject->isKindOf(CC_TYPES::VIEWPORT_2D_OBJECT))
  246. {
  247. fillWithViewportObject(ccHObjectCaster::To2DViewportObject(m_currentObject));
  248. }
  249. else if (m_currentObject->isKindOf(CC_TYPES::GBL_SENSOR))
  250. {
  251. fillWithGBLSensor(ccHObjectCaster::ToGBLSensor(m_currentObject));
  252. }
  253. else if (m_currentObject->isKindOf(CC_TYPES::CAMERA_SENSOR))
  254. {
  255. fillWithCameraSensor(ccHObjectCaster::ToCameraSensor(m_currentObject));
  256. }
  257. else if (m_currentObject->isA(CC_TYPES::MATERIAL_SET))
  258. {
  259. fillWithMaterialSet(static_cast<ccMaterialSet*>(m_currentObject));
  260. }
  261. else if (m_currentObject->isA(CC_TYPES::NORMAL_INDEXES_ARRAY))
  262. {
  263. fillWithCCArray(static_cast<NormsIndexesTableType*>(m_currentObject));
  264. }
  265. else if (m_currentObject->isA(CC_TYPES::TEX_COORDS_ARRAY))
  266. {
  267. fillWithCCArray(static_cast<TextureCoordsContainer*>(m_currentObject));
  268. }
  269. else if (m_currentObject->isA(CC_TYPES::NORMALS_ARRAY))
  270. {
  271. fillWithCCArray(static_cast<NormsTableType*>(m_currentObject));
  272. }
  273. else if (m_currentObject->isA(CC_TYPES::RGB_COLOR_ARRAY))
  274. {
  275. fillWithCCArray(static_cast<ColorsTableType*>(m_currentObject));
  276. }
  277. else if (m_currentObject->isA(CC_TYPES::RGBA_COLOR_ARRAY))
  278. {
  279. fillWithCCArray(static_cast<RGBAColorsTableType*>(m_currentObject));
  280. }
  281. else if (m_currentObject->isA(CC_TYPES::TRANS_BUFFER))
  282. {
  283. fillWithTransBuffer(static_cast<ccIndexedTransformationBuffer*>(m_currentObject));
  284. }
  285. //transformation history
  286. if (m_currentObject->isKindOf(CC_TYPES::POINT_CLOUD)
  287. || m_currentObject->isKindOf(CC_TYPES::MESH)
  288. || m_currentObject->isKindOf(CC_TYPES::FACET)
  289. || m_currentObject->isKindOf(CC_TYPES::POLY_LINE)
  290. || m_currentObject->isKindOf(CC_TYPES::SENSOR))
  291. {
  292. addSeparator( tr( "Transformation history" ) );
  293. appendWideRow(PERSISTENT_EDITOR(OBJECT_HISTORY_MATRIX_EDITOR));
  294. if (m_currentObject->isGLTransEnabled())
  295. {
  296. addSeparator( tr( "Display transformation" ) );
  297. appendWideRow(PERSISTENT_EDITOR(OBJECT_GLTRANS_MATRIX_EDITOR));
  298. }
  299. }
  300. //meta-data
  301. fillWithMetaData(m_currentObject);
  302. //go back to original position
  303. if (scrollPos > 0)
  304. {
  305. m_view->verticalScrollBar()->setSliderPosition(scrollPos);
  306. }
  307. if (m_model)
  308. {
  309. connect(m_model, &QStandardItemModel::itemChanged, this, &ccPropertiesTreeDelegate::updateItem);
  310. }
  311. }
  312. void ccPropertiesTreeDelegate::appendRow(QStandardItem* leftItem, QStandardItem* rightItem, bool openPersistentEditor/*=false*/)
  313. {
  314. assert(leftItem && rightItem);
  315. assert(m_model);
  316. if (m_model)
  317. {
  318. //append row
  319. QList<QStandardItem*> rowItems{ leftItem, rightItem };
  320. m_model->appendRow(rowItems);
  321. //the persistent editor (if any) is always the right one!
  322. if (openPersistentEditor && (m_view != nullptr))
  323. {
  324. m_view->openPersistentEditor(m_model->index(m_model->rowCount() - 1, 1));
  325. }
  326. }
  327. }
  328. void ccPropertiesTreeDelegate::appendWideRow(QStandardItem* item, bool openPersistentEditor/*=true*/)
  329. {
  330. assert(item);
  331. assert(m_model);
  332. if (m_model && item)
  333. {
  334. m_model->appendRow(item);
  335. if (openPersistentEditor && (m_view != nullptr))
  336. {
  337. m_view->openPersistentEditor(m_model->index(m_model->rowCount() - 1, 0));
  338. }
  339. }
  340. }
  341. void ccPropertiesTreeDelegate::addSeparator(const QString& title)
  342. {
  343. if (m_model)
  344. {
  345. //DGM: we can't use the 'text' of the item as it will be displayed under the associated editor (label)!
  346. //So we simply use the 'accessible description' field
  347. QStandardItem* leftItem = new QStandardItem(/*title*/);
  348. leftItem->setData(TREE_VIEW_HEADER);
  349. leftItem->setAccessibleDescription(title);
  350. m_model->appendRow(leftItem);
  351. if ( m_view != nullptr )
  352. {
  353. m_view->openPersistentEditor(m_model->index(m_model->rowCount() - 1, 0));
  354. }
  355. }
  356. }
  357. void ccPropertiesTreeDelegate::fillWithMetaData(const ccObject* _obj)
  358. {
  359. assert(_obj && m_model);
  360. if (!_obj || !m_model)
  361. {
  362. return;
  363. }
  364. const QVariantMap& metaData = _obj->metaData();
  365. if (metaData.empty())
  366. {
  367. return;
  368. }
  369. addSeparator( tr( "Meta data" ) );
  370. for (QVariantMap::ConstIterator it = metaData.constBegin(); it != metaData.constEnd(); ++it)
  371. {
  372. QVariant var = it.value();
  373. QString value;
  374. if (var.canConvert(QVariant::String))
  375. {
  376. var.convert(QVariant::String);
  377. value = var.toString();
  378. }
  379. else
  380. {
  381. value = QString(QVariant::typeToName(var.type()));
  382. }
  383. appendRow(ITEM(it.key()), ITEM(value));
  384. }
  385. }
  386. void ccPropertiesTreeDelegate::fillWithHObject(ccHObject* _obj)
  387. {
  388. assert(_obj && m_model);
  389. if (!_obj || !m_model)
  390. {
  391. return;
  392. }
  393. addSeparator( tr( "CC Object" ) );
  394. //name
  395. appendRow(ITEM( tr( "Name" ) ), ITEM(_obj->getName(), Qt::ItemIsEditable, OBJECT_NAME));
  396. //visibility
  397. if (!_obj->isVisibilityLocked())
  398. {
  399. appendRow(ITEM(tr("Visible")), CHECKABLE_ITEM(_obj->isVisible(), OBJECT_VISIBILITY));
  400. }
  401. //normals
  402. if (_obj->hasNormals())
  403. {
  404. appendRow(ITEM(tr("Normals")), CHECKABLE_ITEM(_obj->normalsShown(), OBJECT_NORMALS_SHOWN));
  405. }
  406. //color source
  407. if (_obj->hasColors() || _obj->hasScalarFields())
  408. {
  409. appendRow(ITEM(tr("Colors")), PERSISTENT_EDITOR(OBJECT_COLOR_SOURCE), true);
  410. }
  411. //Bounding-box
  412. {
  413. ccBBox box;
  414. bool fitBBox = false;
  415. if (_obj->getSelectionBehavior() == ccHObject::SELECTION_FIT_BBOX)
  416. {
  417. ccGLMatrix trans;
  418. box = _obj->getOwnFitBB(trans);
  419. box += trans.getTranslationAsVec3D();
  420. fitBBox = true;
  421. }
  422. else
  423. {
  424. box = _obj->getBB_recursive();
  425. }
  426. if (box.isValid())
  427. {
  428. //name in 3D (we can't display a 3D name if the bounding-box is not valid!
  429. appendRow(ITEM(tr("Show name (in 3D)")), CHECKABLE_ITEM(_obj->nameShownIn3D(), OBJECT_NAME_IN_3D));
  430. //Box dimensions
  431. CCVector3 bboxDiag = box.getDiagVec();
  432. appendRow(ITEM(fitBBox ? tr( "Local box dimensions" ) : tr( "Box dimensions" )),
  433. ITEM(QStringLiteral("X: %1 (%2 : %3)\nY: %4 (%5 : %6)\nZ: %7 (%8 : %9)")
  434. .arg(bboxDiag.x).arg(box.minCorner().x).arg(box.maxCorner().x)
  435. .arg(bboxDiag.y).arg(box.minCorner().y).arg(box.maxCorner().y)
  436. .arg(bboxDiag.z).arg(box.minCorner().z).arg(box.maxCorner().z)
  437. ));
  438. //Box center
  439. CCVector3 bboxCenter = box.getCenter();
  440. ccShiftedObject* shiftedObj = ccHObjectCaster::ToShifted(_obj);
  441. //local bounding box center
  442. appendRow(ITEM(shiftedObj? tr("Shifted box center") : tr("Box center")),
  443. ITEM(QStringLiteral("X: %0\nY: %1\nZ: %2").arg(bboxCenter.x).arg(bboxCenter.y).arg(bboxCenter.z)));
  444. if (shiftedObj)
  445. {
  446. CCVector3d globalBBoxCenter = shiftedObj->toGlobal3d(bboxCenter);
  447. //global bounding box center
  448. appendRow(ITEM(tr("Global box center")),
  449. ITEM(QStringLiteral("X: %0\nY: %1\nZ: %2").arg(globalBBoxCenter.x, 0, 'f').arg(globalBBoxCenter.y, 0, 'f').arg(globalBBoxCenter.z, 0, 'f')));
  450. }
  451. }
  452. }
  453. //infos (unique ID, children) //DGM: on the same line so as to gain space
  454. appendRow(ITEM( tr( "Info" ) ), ITEM( tr("Object ID: %1 - Children: %2").arg(_obj->getUniqueID()).arg(_obj->getChildrenNumber()) ));
  455. //display window
  456. if (!_obj->isLocked())
  457. {
  458. appendRow(ITEM(tr("Current Display")), PERSISTENT_EDITOR(OBJECT_CURRENT_DISPLAY), true);
  459. }
  460. }
  461. void ccPropertiesTreeDelegate::fillWithShifted(const ccShiftedObject* _obj)
  462. {
  463. assert(_obj && m_model);
  464. if (!_obj || !m_model)
  465. {
  466. return;
  467. }
  468. //global shift & scale
  469. const CCVector3d& shift = _obj->getGlobalShift();
  470. appendRow(ITEM( tr( "Global shift" )), ITEM(QStringLiteral("(%1;%2;%3)").arg(shift.x, 0, 'f', 2).arg(shift.y, 0, 'f', 2).arg(shift.z, 0, 'f', 2)));
  471. double scale = _obj->getGlobalScale();
  472. appendRow(ITEM( tr( "Global scale" ) ), ITEM(QStringLiteral("%1").arg(scale, 0, 'f', 6)));
  473. }
  474. void ccPropertiesTreeDelegate::fillWithCoordinateSystem(const ccCoordinateSystem* _obj)
  475. {
  476. assert(_obj && m_model);
  477. if (!_obj || !m_model)
  478. {
  479. return;
  480. }
  481. CCVector3 origin = _obj->getOrigin();
  482. addSeparator(tr("Coordinate System"));
  483. appendRow(ITEM(tr("Origin")),
  484. ITEM(QStringLiteral("X: %0\nY: %1\nZ: %2").arg(origin.x).arg(origin.y).arg(origin.z)));
  485. appendRow(ITEM(tr("Planes Visible")), CHECKABLE_ITEM(_obj->axisPlanesAreShown(), OBJECT_COORDINATE_SYSTEM_DISP_PLANES));
  486. appendRow(ITEM(tr("Planes Stippled")), CHECKABLE_ITEM(static_cast<const ccMesh*>(_obj)->stipplingEnabled(), OBJECT_MESH_STIPPLING));
  487. appendRow(ITEM(tr("Axis Lines Visible")), CHECKABLE_ITEM(_obj->axisLinesAreShown(), OBJECT_COORDINATE_SYSTEM_DISP_AXES));
  488. appendRow(ITEM(tr("Axis width")), PERSISTENT_EDITOR(OBJECT_COORDINATE_SYSTEM_AXES_WIDTH), true);
  489. appendRow(ITEM(tr("Display scale")), PERSISTENT_EDITOR(OBJECT_COORDINATE_SYSTEM_DISP_SCALE), true);
  490. }
  491. void ccPropertiesTreeDelegate::fillWithPointCloud(ccGenericPointCloud* _obj)
  492. {
  493. assert(_obj && m_model);
  494. if (!_obj || !m_model)
  495. {
  496. return;
  497. }
  498. addSeparator( tr( "Cloud" ) );
  499. //number of points
  500. appendRow(ITEM( tr( "Points" ) ), ITEM(QLocale(QLocale::English).toString(_obj->size())));
  501. //global shift & scale
  502. fillWithShifted(_obj);
  503. //custom point size
  504. appendRow(ITEM( tr( "Point size" ) ), PERSISTENT_EDITOR(OBJECT_CLOUD_POINT_SIZE), true);
  505. //scalar field
  506. fillSFWithPointCloud(_obj);
  507. //scan grid structure(s), waveform, etc.
  508. if (_obj->isA(CC_TYPES::POINT_CLOUD))
  509. {
  510. const ccPointCloud* cloud = static_cast<const ccPointCloud*>(_obj);
  511. //scan grid(s)
  512. size_t gridCount = cloud->gridCount();
  513. if (gridCount != 0)
  514. {
  515. if (gridCount != 1)
  516. {
  517. addSeparator(tr("Scan grids"));
  518. }
  519. else
  520. {
  521. addSeparator(tr("Scan grid"));
  522. }
  523. for (size_t i = 0; i < gridCount; ++i)
  524. {
  525. //grid size + valid point count
  526. ccPointCloud::Grid::Shared grid = cloud->grid(i);
  527. appendRow(ITEM(tr("Scan #%1").arg(i + 1)), ITEM(tr("%1 x %2 (%3 points)").arg(grid->w).arg(grid->h).arg(QLocale(QLocale::English).toString(grid->validCount))));
  528. }
  529. }
  530. //waveform
  531. if (cloud->hasFWF())
  532. {
  533. addSeparator( tr( "Waveform" ));
  534. appendRow(ITEM( tr( "Waves" ) ), ITEM(QString::number(cloud->waveforms().size()))); //DGM: in fact some of them might be null/invalid!
  535. appendRow(ITEM( tr("Descriptors" ) ), ITEM(QString::number(cloud->fwfDescriptors().size())));
  536. double dataSize_mb = (cloud->fwfData() ? cloud->fwfData()->size() : 0) / static_cast<double>(1 << 20);
  537. appendRow(ITEM( tr( "Data size" ) ), ITEM(QStringLiteral("%1 Mb").arg(dataSize_mb, 0, 'f', 2)));
  538. }
  539. //normals
  540. if (cloud->hasNormals())
  541. {
  542. fillWithDrawNormals(_obj);
  543. }
  544. }
  545. }
  546. void ccPropertiesTreeDelegate::fillWithDrawNormals(ccGenericPointCloud* _obj)
  547. {
  548. assert(_obj && m_model);
  549. if (!_obj || !m_model)
  550. {
  551. return;
  552. }
  553. assert(_obj->isA(CC_TYPES::POINT_CLOUD));
  554. if (!_obj->isA(CC_TYPES::POINT_CLOUD))
  555. {
  556. return;
  557. }
  558. addSeparator( tr( "Draw normals as lines" ) );
  559. //visibility
  560. const ccPointCloud* cloud = static_cast<const ccPointCloud*>(_obj);
  561. appendRow(ITEM(tr("Draw")), CHECKABLE_ITEM(cloud->normalsAreDrawn(), OBJECT_CLOUD_DRAW_NORMALS));
  562. //normals length
  563. appendRow(ITEM(tr("Length")), PERSISTENT_EDITOR(OBJECT_CLOUD_NORMAL_LENGTH), true);
  564. //normals color
  565. appendRow(ITEM(tr("Color")), PERSISTENT_EDITOR(OBJECT_CLOUD_NORMAL_COLOR), true);
  566. }
  567. void ccPropertiesTreeDelegate::fillSFWithPointCloud(ccGenericPointCloud* _obj)
  568. {
  569. assert(m_model);
  570. if (!_obj || !m_model)
  571. {
  572. return;
  573. }
  574. //for "real" point clouds only
  575. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(_obj);
  576. if (!cloud)
  577. {
  578. return;
  579. }
  580. //Scalar fields
  581. unsigned sfCount = cloud->getNumberOfScalarFields();
  582. if (sfCount != 0)
  583. {
  584. addSeparator(sfCount > 1 ? tr( "Scalar Fields" ) : tr( "Scalar Field" ));
  585. //fields number
  586. appendRow(ITEM( tr( "Count" ) ), ITEM(QString::number(sfCount)));
  587. //fields list combo
  588. appendRow(ITEM( tr( "Active" ) ), PERSISTENT_EDITOR(OBJECT_CURRENT_SCALAR_FIELD), true);
  589. //no need to go any further if no SF is currently active
  590. CCCoreLib::ScalarField* sf = cloud->getCurrentDisplayedScalarField();
  591. if (sf)
  592. {
  593. if (ccLog::VerbosityLevel() == ccLog::LOG_VERBOSE)
  594. {
  595. appendRow(ITEM( tr( "Offset" ) ), ITEM(QString::number(sf->getOffset())));
  596. }
  597. addSeparator("Color Scale");
  598. //color scale selection combo box
  599. appendRow(ITEM( tr( "Current" ) ), PERSISTENT_EDITOR(OBJECT_CURRENT_COLOR_RAMP), true);
  600. //color scale steps
  601. appendRow(ITEM( tr( "Steps" ) ), PERSISTENT_EDITOR(OBJECT_COLOR_RAMP_STEPS), true);
  602. //scale visible?
  603. appendRow(ITEM( tr( "Visible" ) ), CHECKABLE_ITEM(cloud->sfColorScaleShown(), OBJECT_SF_SHOW_SCALE));
  604. addSeparator( tr( "SF display params" ) );
  605. //SF edit dialog (warning: 2 columns)
  606. appendWideRow(PERSISTENT_EDITOR(OBJECT_CLOUD_SF_EDITOR));
  607. }
  608. }
  609. }
  610. void ccPropertiesTreeDelegate::fillWithPrimitive(const ccGenericPrimitive* _obj)
  611. {
  612. assert(_obj && m_model);
  613. if (!_obj || !m_model)
  614. {
  615. return;
  616. }
  617. addSeparator( tr( "Primitive" ) );
  618. //type
  619. appendRow(ITEM( tr( "Type" ) ), ITEM(_obj->getTypeName()));
  620. //drawing steps
  621. if (_obj->hasDrawingPrecision())
  622. {
  623. appendRow(ITEM( tr( "Drawing precision" ) ), PERSISTENT_EDITOR(OBJECT_PRIMITIVE_PRECISION), true);
  624. }
  625. if (_obj->isA(CC_TYPES::SPHERE))
  626. {
  627. appendRow(ITEM( tr( "Radius" ) ), PERSISTENT_EDITOR(OBJECT_SPHERE_RADIUS), true);
  628. }
  629. else if (_obj->isKindOf(CC_TYPES::CONE)) //cylinders are also cones!
  630. {
  631. appendRow(ITEM( tr( "Height" ) ), PERSISTENT_EDITOR(OBJECT_CONE_HEIGHT), true);
  632. if (_obj->isA(CC_TYPES::CYLINDER))
  633. {
  634. appendRow(ITEM( tr( "Radius" ) ), PERSISTENT_EDITOR(OBJECT_CONE_BOTTOM_RADIUS), true);
  635. }
  636. else
  637. {
  638. appendRow(ITEM( tr( "Bottom radius" ) ), PERSISTENT_EDITOR(OBJECT_CONE_BOTTOM_RADIUS), true);
  639. appendRow(ITEM( tr( "Top radius" ) ), PERSISTENT_EDITOR(OBJECT_CONE_TOP_RADIUS), true);
  640. }
  641. const ccCone* cone = static_cast<const ccCone*>(_obj);
  642. CCVector3 apex = cone->computeApex();
  643. appendRow(ITEM(tr("Apex")), ITEM(QStringLiteral("X: %0\nY: %1\nZ: %2").arg(apex.x).arg(apex.y).arg(apex.z)));
  644. double angle_deg = cone->computeHalfAngle_deg();
  645. appendRow(ITEM(tr("Half angle")), ITEM(QStringLiteral("%1 deg.").arg(angle_deg)));
  646. }
  647. else if (_obj->isKindOf(CC_TYPES::PLANE))
  648. {
  649. //planar entity commons
  650. fillWithPlanarEntity(static_cast<const ccPlane*>(_obj));
  651. }
  652. }
  653. void ccPropertiesTreeDelegate::fillWithFacet(const ccFacet* _obj)
  654. {
  655. assert(_obj && m_model);
  656. if (!_obj || !m_model)
  657. {
  658. return;
  659. }
  660. addSeparator(tr("Facet"));
  661. //planar entity commons
  662. fillWithPlanarEntity(_obj);
  663. //surface
  664. appendRow(ITEM(tr("Surface")), ITEM(QLocale(QLocale::English).toString(_obj->getSurface())));
  665. //RMS
  666. appendRow(ITEM(tr("RMS")), ITEM(QLocale(QLocale::English).toString(_obj->getRMS())));
  667. //center
  668. appendRow(ITEM(tr("Center")), ITEM(QStringLiteral("(%1 ; %2 ; %3)").arg(_obj->getCenter().x).arg(_obj->getCenter().y).arg(_obj->getCenter().z)));
  669. //contour visibility
  670. if (_obj->getContour())
  671. {
  672. appendRow(ITEM(tr("Show contour")), CHECKABLE_ITEM(_obj->getContour()->isVisible(), OBJECT_FACET_CONTOUR));
  673. }
  674. //polygon visibility
  675. if (_obj->getPolygon())
  676. {
  677. appendRow(ITEM(tr("Show polygon")), CHECKABLE_ITEM(_obj->getPolygon()->isVisible(), OBJECT_FACET_MESH));
  678. }
  679. }
  680. void ccPropertiesTreeDelegate::fillWithPlanarEntity(const ccPlanarEntityInterface* _obj)
  681. {
  682. if (!_obj || !m_model)
  683. {
  684. return;
  685. }
  686. //normal
  687. CCVector3 N = _obj->getNormal();
  688. appendRow(ITEM( tr( "Normal" ) ), ITEM(QStringLiteral("(%1 ; %2 ; %3)").arg(N.x).arg(N.y).arg(N.z)));
  689. //Dip & Dip direction (in degrees)
  690. PointCoordinateType dip_deg;
  691. PointCoordinateType dipDir_deg;
  692. ccNormalVectors::ConvertNormalToDipAndDipDir(N, dip_deg, dipDir_deg);
  693. appendRow(ITEM( tr( "Dip / Dip dir. (integer)" ) ), ITEM(QStringLiteral("(%1 ; %2) deg.").arg(static_cast<int>(std::round(dip_deg))).arg(static_cast<int>(std::round(dipDir_deg)))));
  694. appendRow(ITEM( tr( "Dip / Dip dir." ) ), ITEM(QStringLiteral("(%1; %2) deg.").arg(dip_deg, 0, 'f', 2).arg(dipDir_deg, 0, 'f', 2)));
  695. //normal vector visibility
  696. appendRow(ITEM( tr( "Show normal vector" ) ), CHECKABLE_ITEM(_obj->normalVectorIsShown(), OBJECT_PLANE_NORMAL_VECTOR));
  697. }
  698. void ccPropertiesTreeDelegate::fillWithMesh(const ccGenericMesh* _obj)
  699. {
  700. assert(_obj && m_model);
  701. if (!_obj || !m_model)
  702. {
  703. return;
  704. }
  705. bool isSubMesh = _obj->isA(CC_TYPES::SUB_MESH);
  706. addSeparator(isSubMesh ? tr( "Sub-mesh" ) : tr( "Mesh" ) );
  707. //number of facets
  708. appendRow(ITEM( tr( "Faces" ) ), ITEM(QLocale(QLocale::English).toString(_obj->size())));
  709. //material/texture
  710. if (_obj->hasMaterials())
  711. appendRow(ITEM( tr( "Materials/textures" ) ), CHECKABLE_ITEM(_obj->materialsShown(), OBJECT_MATERIALS));
  712. //wireframe
  713. appendRow(ITEM( tr( "Wireframe" ) ), CHECKABLE_ITEM(_obj->isShownAsWire(), OBJECT_MESH_WIRE));
  714. //stippling (ccMesh only)
  715. //if (_obj->isA(CC_TYPES::MESH)) //DGM: can't remember why?
  716. appendRow(ITEM( tr( "Stippling" ) ), CHECKABLE_ITEM(static_cast<const ccMesh*>(_obj)->stipplingEnabled(), OBJECT_MESH_STIPPLING));
  717. //we also integrate vertices SF into mesh properties
  718. ccGenericPointCloud* vertices = _obj->getAssociatedCloud();
  719. if (vertices && (!vertices->isLocked() || _obj->isAncestorOf(vertices)))
  720. {
  721. fillSFWithPointCloud(vertices);
  722. }
  723. //global shift & scale
  724. fillWithShifted(_obj);
  725. }
  726. void ccPropertiesTreeDelegate::fillWithPolyline(const ccPolyline* _obj)
  727. {
  728. assert(_obj && m_model);
  729. if (!_obj || !m_model)
  730. {
  731. return;
  732. }
  733. addSeparator( tr( "Polyline" ) );
  734. //number of vertices
  735. appendRow(ITEM( tr( "Vertices" ) ), ITEM(QLocale(QLocale::English).toString(_obj->size())));
  736. //polyline length
  737. appendRow(ITEM( tr( "Length" ) ), ITEM(QLocale(QLocale::English).toString(_obj->computeLength())));
  738. //custom line width
  739. appendRow(ITEM( tr( "Line width" ) ), PERSISTENT_EDITOR(OBJECT_POLYLINE_WIDTH), true);
  740. //global shift & scale
  741. fillWithShifted(_obj);
  742. }
  743. void ccPropertiesTreeDelegate::fillWithPointOctree(const ccOctree* _obj)
  744. {
  745. assert(_obj && m_model);
  746. if (!_obj || !m_model)
  747. {
  748. return;
  749. }
  750. addSeparator( tr( "Octree" ) );
  751. //display mode
  752. appendRow(ITEM( tr( "Display mode" ) ), PERSISTENT_EDITOR(OBJECT_OCTREE_TYPE), true);
  753. //level
  754. appendRow(ITEM( tr( "Display level" ) ), PERSISTENT_EDITOR(OBJECT_OCTREE_LEVEL), true);
  755. addSeparator( tr( "Current level" ) );
  756. //current display level
  757. int level = _obj->getDisplayedLevel();
  758. assert(level > 0 && level <= ccOctree::MAX_OCTREE_LEVEL);
  759. //cell size
  760. const double cellSize = static_cast<double>(_obj->getCellSize(static_cast<unsigned char>(level)));
  761. appendRow(ITEM( tr( "Cell size" ) ), ITEM(QString::number(cellSize)));
  762. //cell count
  763. unsigned cellCount = _obj->getCellNumber(static_cast<unsigned char>(level));
  764. appendRow(ITEM( tr( "Cell count" ) ), ITEM(QLocale(QLocale::English).toString(cellCount)));
  765. //total volume of filled cells
  766. appendRow(ITEM( tr( "Filled volume" ) ), ITEM(QString::number(cellCount*pow(cellSize, 3.0))));
  767. }
  768. void ccPropertiesTreeDelegate::fillWithPointKdTree(const ccKdTree* _obj)
  769. {
  770. assert(_obj && m_model);
  771. if (!_obj || !m_model)
  772. {
  773. return;
  774. }
  775. addSeparator( tr( "Kd-tree" ) );
  776. //max error
  777. appendRow(ITEM( tr( "Max Error" ) ), ITEM(QString::number(_obj->getMaxError())));
  778. //max error measure
  779. {
  780. QString errorMeasure;
  781. switch (_obj->getMaxErrorType())
  782. {
  783. case CCCoreLib::DistanceComputationTools::RMS:
  784. errorMeasure = tr( "RMS" );
  785. break;
  786. case CCCoreLib::DistanceComputationTools::MAX_DIST_68_PERCENT:
  787. errorMeasure = tr( "Max dist @ 68%" );
  788. break;
  789. case CCCoreLib::DistanceComputationTools::MAX_DIST_95_PERCENT:
  790. errorMeasure = tr( "Max dist @ 95%" );
  791. break;
  792. case CCCoreLib::DistanceComputationTools::MAX_DIST_99_PERCENT:
  793. errorMeasure = tr( "Max dist @ 99%" );
  794. break;
  795. case CCCoreLib::DistanceComputationTools::MAX_DIST:
  796. errorMeasure = tr( "Max distance" );
  797. break;
  798. default:
  799. assert(false);
  800. errorMeasure = tr( "unknown" );
  801. break;
  802. }
  803. appendRow(ITEM( tr( "Error measure" ) ), ITEM(errorMeasure));
  804. }
  805. }
  806. void ccPropertiesTreeDelegate::fillWithImage(const ccImage* _obj)
  807. {
  808. assert(_obj && m_model);
  809. if (!_obj || !m_model)
  810. {
  811. return;
  812. }
  813. addSeparator( tr( "Image" ));
  814. //image width
  815. appendRow(ITEM( tr( "Width" ) ), ITEM(QString::number(_obj->getW())));
  816. //image height
  817. appendRow(ITEM( tr( "Height" ) ), ITEM(QString::number(_obj->getH())));
  818. //transparency
  819. appendRow(ITEM( tr( "Alpha" ) ), PERSISTENT_EDITOR(OBJECT_IMAGE_ALPHA), true);
  820. if (_obj->getAssociatedSensor())
  821. {
  822. addSeparator( tr( "Sensor" ) );
  823. //"Set Viewport" button (shortcut to associated sensor)
  824. appendRow(ITEM( tr( "Apply Viewport" ) ), PERSISTENT_EDITOR(OBJECT_APPLY_IMAGE_VIEWPORT), true);
  825. }
  826. }
  827. void ccPropertiesTreeDelegate::fillWithLabel(const cc2DLabel* _obj)
  828. {
  829. assert(_obj && m_model);
  830. if (!_obj || !m_model)
  831. {
  832. return;
  833. }
  834. addSeparator( tr( "Label" ) );
  835. //Body
  836. QStringList body = _obj->getLabelContent(ccGui::Parameters().displayedNumPrecision);
  837. appendRow(ITEM( tr( "Body" ) ), ITEM(body.join("\n")));
  838. //Show label in 2D
  839. appendRow(ITEM( tr( "Show 2D label" ) ), CHECKABLE_ITEM(_obj->isDisplayedIn2D(), OBJECT_LABEL_DISP_2D));
  840. //Show label in 3D
  841. appendRow(ITEM( tr( "Show legend(s)" ) ), CHECKABLE_ITEM(_obj->isPointLegendDisplayed(), OBJECT_LABEL_POINT_LEGEND));
  842. }
  843. void ccPropertiesTreeDelegate::fillWithViewportObject(const cc2DViewportObject* _obj)
  844. {
  845. assert(_obj && m_model);
  846. if (!_obj || !m_model)
  847. {
  848. return;
  849. }
  850. addSeparator( tr( "Viewport" ) );
  851. //Name
  852. appendRow(ITEM( tr( "Name" ) ), ITEM(_obj->getName().isEmpty() ? tr( "undefined" ) : _obj->getName()));
  853. //"Apply Viewport" button
  854. appendRow(ITEM( tr( "Apply viewport" ) ), PERSISTENT_EDITOR(OBJECT_APPLY_LABEL_VIEWPORT), true);
  855. //"Update Viewport" button
  856. appendRow(ITEM( tr( "Update viewport" ) ), PERSISTENT_EDITOR(OBJECT_UPDATE_LABEL_VIEWPORT), true);
  857. }
  858. void ccPropertiesTreeDelegate::fillWithTransBuffer(const ccIndexedTransformationBuffer* _obj)
  859. {
  860. assert(_obj && m_model);
  861. if (!_obj || !m_model)
  862. {
  863. return;
  864. }
  865. addSeparator( tr( "Trans. buffer" ) );
  866. //Associated positions
  867. appendRow(ITEM( tr( "Count" ) ), ITEM(QString::number(_obj->size())));
  868. //Show path as polyline
  869. appendRow(ITEM( tr( "Show path" ) ), CHECKABLE_ITEM(_obj->isPathShownAsPolyline(), OBJECT_SHOW_TRANS_BUFFER_PATH));
  870. //Show trihedrons
  871. appendRow(ITEM( tr( "Show trihedrons" ) ), CHECKABLE_ITEM(_obj->trihedronsShown(), OBJECT_SHOW_TRANS_BUFFER_TRIHDERONS));
  872. //Trihedrons scale
  873. appendRow(ITEM( tr( "Scale" ) ), PERSISTENT_EDITOR(OBJECT_TRANS_BUFFER_TRIHDERONS_SCALE), true);
  874. }
  875. void ccPropertiesTreeDelegate::fillWithSensor(const ccSensor* _obj)
  876. {
  877. assert(_obj && m_model);
  878. if (!_obj || !m_model)
  879. {
  880. return;
  881. }
  882. //Sensor drawing scale
  883. appendRow(ITEM( tr( "Drawing scale" ) ), PERSISTENT_EDITOR(OBJECT_SENSOR_DISPLAY_SCALE), true);
  884. //"Apply Viewport" button
  885. appendRow(ITEM( tr( "Apply Viewport" ) ), PERSISTENT_EDITOR(OBJECT_APPLY_SENSOR_VIEWPORT), true);
  886. //sensor aboslute orientation
  887. addSeparator( tr( "Position/Orientation" ) );
  888. appendWideRow(PERSISTENT_EDITOR(OBJECT_SENSOR_MATRIX_EDITOR));
  889. //Associated positions
  890. addSeparator( tr( "Associated positions" ) );
  891. //number of positions
  892. appendRow(ITEM( tr( "Count" ) ), ITEM(QString::number(_obj->getPositions() ? _obj->getPositions()->size() : 0)));
  893. double minIndex = 0.0;
  894. double maxIndex = 0.0;
  895. _obj->getIndexBounds(minIndex, maxIndex);
  896. if (minIndex != maxIndex)
  897. {
  898. //Index span
  899. appendRow(ITEM( tr( "Indices" ) ), ITEM(QStringLiteral("%1 - %2").arg(minIndex).arg(maxIndex)));
  900. //Current index
  901. appendRow(ITEM( tr( "Active index" ) ), PERSISTENT_EDITOR(OBJECT_SENSOR_INDEX), true);
  902. }
  903. }
  904. void ccPropertiesTreeDelegate::fillWithGBLSensor(const ccGBLSensor* _obj)
  905. {
  906. assert(_obj && m_model);
  907. if (!_obj || !m_model)
  908. {
  909. return;
  910. }
  911. addSeparator( tr( "TLS/GBL Sensor" ) );
  912. //Uncertainty
  913. appendRow(ITEM( tr( "Uncertainty" ) ), PERSISTENT_EDITOR(OBJECT_SENSOR_UNCERTAINTY), true);
  914. //angles
  915. addSeparator( tr( "Angular viewport (degrees)" ) );
  916. {
  917. //Angular range (yaw)
  918. PointCoordinateType yawMin = _obj->getMinYaw();
  919. PointCoordinateType yawMax = _obj->getMaxYaw();
  920. appendRow(ITEM( tr( "Yaw span" ) ),
  921. ITEM( QStringLiteral("[%1 ; %2]")
  922. .arg( CCCoreLib::RadiansToDegrees( yawMin ), 0, 'f', 2)
  923. .arg( CCCoreLib::RadiansToDegrees( yawMax ), 0, 'f', 2)));
  924. //Angular steps (yaw)
  925. PointCoordinateType yawStep = _obj->getYawStep();
  926. appendRow(ITEM( tr( "Yaw step" ) ),
  927. ITEM( QStringLiteral("%1")
  928. .arg( CCCoreLib::RadiansToDegrees( yawStep ), 0, 'f', 4)));
  929. //Angular range (pitch)
  930. PointCoordinateType pitchMin = _obj->getMinPitch();
  931. PointCoordinateType pitchMax = _obj->getMaxPitch();
  932. appendRow(ITEM( tr( "Pitch span" ) ),
  933. ITEM( QStringLiteral("[%1 ; %2]")
  934. .arg( CCCoreLib::RadiansToDegrees( pitchMin ), 0, 'f', 2)
  935. .arg( CCCoreLib::RadiansToDegrees( pitchMax ), 0, 'f', 2)));
  936. //Angular steps (pitch)
  937. PointCoordinateType pitchStep = _obj->getPitchStep();
  938. appendRow(ITEM( tr( "Pitch step" ) ),
  939. ITEM( QStringLiteral("%1")
  940. .arg( CCCoreLib::RadiansToDegrees( pitchStep ), 0, 'f', 4)));
  941. }
  942. //Positions
  943. fillWithSensor(_obj);
  944. }
  945. void ccPropertiesTreeDelegate::fillWithCameraSensor(const ccCameraSensor* _obj)
  946. {
  947. assert(_obj && m_model);
  948. if (!_obj || !m_model)
  949. {
  950. return;
  951. }
  952. addSeparator( tr( "Camera Sensor" ) );
  953. const ccCameraSensor::IntrinsicParameters& params = _obj->getIntrinsicParameters();
  954. //Focal
  955. appendRow(ITEM( tr( "Vert. focal" ) ), ITEM(QString::number(params.vertFocal_pix) + " pix."));
  956. //Array size
  957. appendRow(ITEM( tr( "Array size" ) ), ITEM(QStringLiteral("%1 x %2").arg(params.arrayWidth).arg(params.arrayHeight)));
  958. //Principal point
  959. appendRow(ITEM( tr( "Principal point" ) ), ITEM(QStringLiteral("(%1 ; %2)").arg(params.principal_point[0]).arg(params.principal_point[1])));
  960. //Pixel size
  961. if (params.pixelSize_mm[0] != 0 || params.pixelSize_mm[1] != 0)
  962. {
  963. appendRow(ITEM( tr( "Pixel size" ) ), ITEM(QStringLiteral("%1 x %2").arg(params.pixelSize_mm[0]).arg(params.pixelSize_mm[1])));
  964. }
  965. //Field of view
  966. appendRow(ITEM( tr( "Field of view" ) ), ITEM(QString::number( CCCoreLib::RadiansToDegrees( params.vFOV_rad ) ) + " deg."));
  967. //Skewness
  968. appendRow(ITEM( tr( "Skew" ) ), ITEM(QString::number(params.skew)));
  969. addSeparator( tr( "Frustum display" ) );
  970. //Draw frustum
  971. appendRow(ITEM( tr( "Show lines" ) ), CHECKABLE_ITEM(_obj->frustumIsDrawn(), OBJECT_SENSOR_DRAW_FRUSTUM));
  972. appendRow(ITEM( tr( "Show side planes" ) ), CHECKABLE_ITEM(_obj->frustumPlanesAreDrawn(), OBJECT_SENSOR_DRAW_FRUSTUM_PLANES));
  973. //Positions
  974. fillWithSensor(_obj);
  975. }
  976. void ccPropertiesTreeDelegate::fillWithMaterialSet(const ccMaterialSet* _obj)
  977. {
  978. assert(_obj && m_model);
  979. if (!_obj || !m_model)
  980. {
  981. return;
  982. }
  983. addSeparator( tr( "Material set" ) );
  984. //Count
  985. appendRow(ITEM( tr( "Count" ) ), ITEM(QString::number(_obj->size())));
  986. //ccMaterialSet objects are 'shareable'
  987. fillWithShareable(_obj);
  988. }
  989. void ccPropertiesTreeDelegate::fillWithShareable(const CCShareable* _obj)
  990. {
  991. assert(_obj && m_model);
  992. if (!_obj || !m_model)
  993. {
  994. return;
  995. }
  996. addSeparator( tr( "Array" ) );
  997. //Link count
  998. unsigned linkCount = _obj->getLinkCount(); //if we display it, it means it is a member of the DB --> i.e. link is already >1
  999. appendRow(ITEM( tr( "Shared" ) ), ITEM(linkCount < 3 ? tr("No") : tr("Yes (%1)").arg(linkCount - 1)));
  1000. }
  1001. template<class Type, int N, class ComponentType>
  1002. void ccPropertiesTreeDelegate::fillWithCCArray(const ccArray<Type, N, ComponentType>* _obj)
  1003. {
  1004. assert(_obj && m_model);
  1005. if (!_obj || !m_model)
  1006. {
  1007. return;
  1008. }
  1009. addSeparator( tr( "Array" ) );
  1010. //Name
  1011. appendRow(ITEM( tr( "Name" ) ), ITEM(_obj->getName().isEmpty() ? tr( "undefined" ) : _obj->getName()));
  1012. //Count
  1013. appendRow(ITEM( tr( "Elements" ) ), ITEM(QLocale(QLocale::English).toString(static_cast<qulonglong>(_obj->size()))));
  1014. //Capacity
  1015. appendRow(ITEM( tr( "Capacity" ) ), ITEM(QLocale(QLocale::English).toString(static_cast<qulonglong>(_obj->capacity()))));
  1016. //Memory
  1017. appendRow(ITEM( tr( "Memory" ) ), ITEM(QStringLiteral("%1 Mb").arg((_obj->capacity() * sizeof(Type)) / 1048576.0, 0, 'f', 2)));
  1018. //ccArray objects are 'Shareable'
  1019. fillWithShareable(_obj);
  1020. }
  1021. bool ccPropertiesTreeDelegate::isWideEditor(int itemData) const
  1022. {
  1023. switch (itemData)
  1024. {
  1025. case OBJECT_CLOUD_SF_EDITOR:
  1026. case OBJECT_SENSOR_MATRIX_EDITOR:
  1027. case OBJECT_HISTORY_MATRIX_EDITOR:
  1028. case OBJECT_GLTRANS_MATRIX_EDITOR:
  1029. case TREE_VIEW_HEADER:
  1030. return true;
  1031. default:
  1032. break;
  1033. }
  1034. return false;
  1035. }
  1036. QWidget* ccPropertiesTreeDelegate::createEditor(QWidget *parent,
  1037. const QStyleOptionViewItem &option,
  1038. const QModelIndex &index) const
  1039. {
  1040. if (!m_model || !m_currentObject)
  1041. return nullptr;
  1042. QStandardItem* item = m_model->itemFromIndex(index);
  1043. if (!item || !item->data().isValid())
  1044. return nullptr;
  1045. int itemData = item->data().toInt();
  1046. if (item->column() == 0 && !isWideEditor(itemData))
  1047. {
  1048. //on the first column, only editors spanning on 2 columns are allowed
  1049. return nullptr;
  1050. }
  1051. QWidget* outputWidget = nullptr;
  1052. switch (itemData)
  1053. {
  1054. case OBJECT_CURRENT_DISPLAY:
  1055. {
  1056. QComboBox *comboBox = new QComboBox(parent);
  1057. std::vector<ccGLWindowInterface*> glWindows;
  1058. MainWindow::GetGLWindows(glWindows);
  1059. comboBox->addItem( tr( s_noneString ) );
  1060. for (auto &glWindow : glWindows)
  1061. {
  1062. comboBox->addItem(glWindow->getWindowTitle());
  1063. }
  1064. connect(comboBox, qOverload<const QString&>(&QComboBox::currentIndexChanged),
  1065. this, &ccPropertiesTreeDelegate::objectDisplayChanged);
  1066. outputWidget = comboBox;
  1067. }
  1068. break;
  1069. case OBJECT_CURRENT_SCALAR_FIELD:
  1070. {
  1071. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  1072. assert(cloud);
  1073. QComboBox *comboBox = new QComboBox(parent);
  1074. comboBox->addItem( tr( s_noneString ) );
  1075. int nsf = cloud ? cloud->getNumberOfScalarFields() : 0;
  1076. for (int i = 0; i < nsf; ++i)
  1077. {
  1078. comboBox->addItem(QString::fromStdString(cloud->getScalarFieldName(i)));
  1079. }
  1080. connect(comboBox, qOverload<int>(&QComboBox::activated),
  1081. this, &ccPropertiesTreeDelegate::scalarFieldChanged);
  1082. outputWidget = comboBox;
  1083. }
  1084. break;
  1085. case OBJECT_CURRENT_COLOR_RAMP:
  1086. {
  1087. ccColorScaleSelector* selector = new ccColorScaleSelector(ccColorScalesManager::GetUniqueInstance(), parent, QString::fromUtf8(":/CC/images/ccGear.png"));
  1088. //fill combobox box with Color Scales Manager
  1089. selector->init();
  1090. connect(selector, &ccColorScaleSelector::colorScaleSelected, this, &ccPropertiesTreeDelegate::colorScaleChanged);
  1091. connect(selector, &ccColorScaleSelector::colorScaleEditorSummoned, this, &ccPropertiesTreeDelegate::spawnColorRampEditor);
  1092. outputWidget = selector;
  1093. }
  1094. break;
  1095. case OBJECT_COLOR_RAMP_STEPS:
  1096. {
  1097. QSpinBox *spinBox = new QSpinBox(parent);
  1098. spinBox->setRange(ccColorScale::MIN_STEPS, ccColorScale::MAX_STEPS);
  1099. spinBox->setSingleStep(4);
  1100. connect(spinBox, qOverload<int>(&QSpinBox::valueChanged),
  1101. this, &ccPropertiesTreeDelegate::colorRampStepsChanged);
  1102. outputWidget = spinBox;
  1103. }
  1104. break;
  1105. case OBJECT_CLOUD_SF_EDITOR:
  1106. {
  1107. sfEditDlg* sfd = new sfEditDlg(parent);
  1108. //DGM: why does this widget can't follow its 'policy' ?!
  1109. //QSizePolicy pol = sfd->sizePolicy();
  1110. //QSizePolicy::Policy hpol = pol.horizontalPolicy();
  1111. //sfd->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Maximum);
  1112. //parent->setSizePolicy(QSizePolicy::Minimum,QSizePolicy::Maximum);
  1113. connect(sfd, &sfEditDlg::entitySFHasChanged, this, &ccPropertiesTreeDelegate::updateDisplay);
  1114. outputWidget = sfd;
  1115. }
  1116. break;
  1117. case OBJECT_HISTORY_MATRIX_EDITOR:
  1118. case OBJECT_GLTRANS_MATRIX_EDITOR:
  1119. case OBJECT_SENSOR_MATRIX_EDITOR:
  1120. {
  1121. MatrixDisplayDlg* mdd = new MatrixDisplayDlg(parent);
  1122. //no signal connection, it's a display-only widget
  1123. outputWidget = mdd;
  1124. }
  1125. break;
  1126. case TREE_VIEW_HEADER:
  1127. {
  1128. QLabel* headerLabel = new QLabel(parent);
  1129. headerLabel->setStyleSheet(SEPARATOR_STYLESHEET);
  1130. //no signal connection, it's a display-only widget
  1131. outputWidget = headerLabel;
  1132. }
  1133. break;
  1134. case OBJECT_OCTREE_TYPE:
  1135. {
  1136. QComboBox* comboBox = new QComboBox(parent);
  1137. comboBox->addItem( tr( "Wire" ), QVariant(ccOctree::WIRE) );
  1138. comboBox->addItem( tr( "Points" ), QVariant(ccOctree::MEAN_POINTS) );
  1139. comboBox->addItem( tr( "Plain cubes" ), QVariant(ccOctree::MEAN_CUBES) );
  1140. connect(comboBox, qOverload<int>(&QComboBox::activated),
  1141. this, &ccPropertiesTreeDelegate::octreeDisplayModeChanged);
  1142. outputWidget = comboBox;
  1143. }
  1144. break;
  1145. case OBJECT_OCTREE_LEVEL:
  1146. {
  1147. QSpinBox* spinBox = new QSpinBox(parent);
  1148. spinBox->setRange(1, CCCoreLib::DgmOctree::MAX_OCTREE_LEVEL);
  1149. connect(spinBox, qOverload<int>(&QSpinBox::valueChanged),
  1150. this, &ccPropertiesTreeDelegate::octreeDisplayedLevelChanged);
  1151. outputWidget = spinBox;
  1152. }
  1153. break;
  1154. case OBJECT_PRIMITIVE_PRECISION:
  1155. {
  1156. QSpinBox* spinBox = new QSpinBox(parent);
  1157. spinBox->setRange(4, 1024);
  1158. spinBox->setSingleStep(4);
  1159. connect(spinBox, qOverload<int>(&QSpinBox::valueChanged),
  1160. this, &ccPropertiesTreeDelegate::primitivePrecisionChanged);
  1161. outputWidget = spinBox;
  1162. }
  1163. break;
  1164. case OBJECT_SPHERE_RADIUS:
  1165. {
  1166. QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent);
  1167. spinBox->setDecimals(6);
  1168. spinBox->setRange(0, 1.0e6);
  1169. spinBox->setSingleStep(1.0);
  1170. connect(spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
  1171. this, &ccPropertiesTreeDelegate::sphereRadiusChanged);
  1172. outputWidget = spinBox;
  1173. }
  1174. break;
  1175. case OBJECT_CONE_HEIGHT:
  1176. {
  1177. QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent);
  1178. spinBox->setDecimals(6);
  1179. spinBox->setRange(0, 1.0e6);
  1180. spinBox->setSingleStep(1.0);
  1181. connect(spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
  1182. this, &ccPropertiesTreeDelegate::coneHeightChanged);
  1183. outputWidget = spinBox;
  1184. }
  1185. break;
  1186. case OBJECT_CONE_BOTTOM_RADIUS:
  1187. {
  1188. QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent);
  1189. spinBox->setDecimals(6);
  1190. spinBox->setRange(0, 1.0e6);
  1191. spinBox->setSingleStep(1.0);
  1192. connect(spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
  1193. this, &ccPropertiesTreeDelegate::coneBottomRadiusChanged);
  1194. outputWidget = spinBox;
  1195. }
  1196. break;
  1197. case OBJECT_CONE_TOP_RADIUS:
  1198. {
  1199. QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent);
  1200. spinBox->setDecimals(6);
  1201. spinBox->setRange(0, 1.0e6);
  1202. spinBox->setSingleStep(1.0);
  1203. connect(spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
  1204. this, &ccPropertiesTreeDelegate::coneTopRadiusChanged);
  1205. outputWidget = spinBox;
  1206. }
  1207. break;
  1208. case OBJECT_IMAGE_ALPHA:
  1209. {
  1210. QSlider* slider = new QSlider(Qt::Horizontal, parent);
  1211. slider->setRange(0, 255);
  1212. slider->setSingleStep(1);
  1213. slider->setPageStep(16);
  1214. slider->setTickPosition(QSlider::NoTicks);
  1215. connect(slider, &QAbstractSlider::valueChanged, this, &ccPropertiesTreeDelegate::imageAlphaChanged);
  1216. outputWidget = slider;
  1217. }
  1218. break;
  1219. case OBJECT_SENSOR_INDEX:
  1220. {
  1221. ccSensor* sensor = ccHObjectCaster::ToSensor(m_currentObject);
  1222. assert(sensor);
  1223. double minIndex = 0.0;
  1224. double maxIndex = 0.0;
  1225. if (sensor)
  1226. {
  1227. sensor->getIndexBounds(minIndex, maxIndex);
  1228. }
  1229. QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent);
  1230. spinBox->setRange(minIndex, maxIndex);
  1231. spinBox->setSingleStep((maxIndex - minIndex) / 1000.0);
  1232. connect(spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
  1233. this, &ccPropertiesTreeDelegate::sensorIndexChanged);
  1234. outputWidget = spinBox;
  1235. }
  1236. break;
  1237. case OBJECT_TRANS_BUFFER_TRIHDERONS_SCALE:
  1238. {
  1239. QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent);
  1240. spinBox->setRange(1.0e-3, 1.0e6);
  1241. spinBox->setDecimals(3);
  1242. spinBox->setSingleStep(1.0);
  1243. connect(spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
  1244. this, &ccPropertiesTreeDelegate::trihedronsScaleChanged);
  1245. outputWidget = spinBox;
  1246. }
  1247. break;
  1248. case OBJECT_APPLY_IMAGE_VIEWPORT:
  1249. {
  1250. QPushButton* button = new QPushButton( tr( "Apply" ), parent );
  1251. connect(button, &QAbstractButton::clicked, this, &ccPropertiesTreeDelegate::applyImageViewport);
  1252. button->setMinimumHeight(30);
  1253. outputWidget = button;
  1254. }
  1255. break;
  1256. case OBJECT_APPLY_SENSOR_VIEWPORT:
  1257. {
  1258. QPushButton* button = new QPushButton( tr( "Apply" ), parent );
  1259. connect(button, &QAbstractButton::clicked, this, &ccPropertiesTreeDelegate::applySensorViewport);
  1260. button->setMinimumHeight(30);
  1261. outputWidget = button;
  1262. }
  1263. break;
  1264. case OBJECT_APPLY_LABEL_VIEWPORT:
  1265. {
  1266. QPushButton* button = new QPushButton( tr( "Apply" ), parent );
  1267. connect(button, &QAbstractButton::clicked, this, &ccPropertiesTreeDelegate::applyLabelViewport);
  1268. button->setMinimumHeight(30);
  1269. outputWidget = button;
  1270. }
  1271. break;
  1272. case OBJECT_UPDATE_LABEL_VIEWPORT:
  1273. {
  1274. QPushButton* button = new QPushButton( tr( "Update" ), parent );
  1275. connect(button, &QAbstractButton::clicked, this, &ccPropertiesTreeDelegate::updateLabelViewport);
  1276. button->setMinimumHeight(30);
  1277. outputWidget = button;
  1278. }
  1279. break;
  1280. case OBJECT_SENSOR_UNCERTAINTY:
  1281. {
  1282. QLineEdit* lineEdit = new QLineEdit(parent);
  1283. lineEdit->setValidator(new QDoubleValidator(1.0e-8, 1.0, 8, lineEdit));
  1284. connect(lineEdit, &QLineEdit::editingFinished, this, &ccPropertiesTreeDelegate::sensorUncertaintyChanged);
  1285. outputWidget = lineEdit;
  1286. }
  1287. break;
  1288. case OBJECT_SENSOR_DISPLAY_SCALE:
  1289. {
  1290. QDoubleSpinBox *spinBox = new QDoubleSpinBox(parent);
  1291. spinBox->setRange(1.0e-3, 1.0e6);
  1292. spinBox->setDecimals(3);
  1293. spinBox->setSingleStep(1.0e-1);
  1294. connect(spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
  1295. this, &ccPropertiesTreeDelegate::sensorScaleChanged);
  1296. outputWidget = spinBox;
  1297. }
  1298. break;
  1299. case OBJECT_CLOUD_POINT_SIZE:
  1300. {
  1301. QComboBox *comboBox = new QComboBox(parent);
  1302. comboBox->addItem( tr( s_defaultPointSizeString ) ); //size = 0
  1303. for (int i = static_cast<int>(ccGLWindowInterface::MIN_POINT_SIZE_F); i <= static_cast<int>(ccGLWindowInterface::MAX_POINT_SIZE_F); ++i)
  1304. {
  1305. comboBox->addItem(QString::number(i));
  1306. }
  1307. connect(comboBox, qOverload<int>(&QComboBox::currentIndexChanged),
  1308. this, &ccPropertiesTreeDelegate::cloudPointSizeChanged);
  1309. outputWidget = comboBox;
  1310. }
  1311. break;
  1312. case OBJECT_POLYLINE_WIDTH:
  1313. {
  1314. QComboBox *comboBox = new QComboBox(parent);
  1315. comboBox->addItem( tr( s_defaultPolyWidthSizeString ) ); //size = 0
  1316. for (int i = static_cast<int>(ccGLWindowInterface::MIN_LINE_WIDTH_F); i <= static_cast<int>(ccGLWindowInterface::MAX_LINE_WIDTH_F); ++i)
  1317. {
  1318. comboBox->addItem(QString::number(i));
  1319. }
  1320. connect(comboBox, qOverload<int>(&QComboBox::currentIndexChanged),
  1321. this, &ccPropertiesTreeDelegate::polyineWidthChanged);
  1322. outputWidget = comboBox;
  1323. }
  1324. break;
  1325. case OBJECT_COLOR_SOURCE:
  1326. {
  1327. QComboBox *comboBox = new QComboBox(parent);
  1328. comboBox->addItem( tr( s_noneString ) );
  1329. if (m_currentObject)
  1330. {
  1331. if (m_currentObject->hasColors())
  1332. {
  1333. comboBox->addItem(s_rgbColor);
  1334. comboBox->setItemIcon(comboBox->count() - 1, QIcon(QString::fromUtf8(":/CC/images/typeRgbCcolor.png")));
  1335. }
  1336. if (m_currentObject->hasScalarFields())
  1337. {
  1338. comboBox->addItem( tr( s_sfColor ) );
  1339. comboBox->setItemIcon(comboBox->count() - 1, QIcon(QString::fromUtf8(":/CC/images/typeSF.png")));
  1340. }
  1341. connect(comboBox, qOverload<const QString&>(&QComboBox::currentIndexChanged),
  1342. this, &ccPropertiesTreeDelegate::colorSourceChanged);
  1343. }
  1344. outputWidget = comboBox;
  1345. }
  1346. break;
  1347. case OBJECT_COORDINATE_SYSTEM_AXES_WIDTH:
  1348. {
  1349. QComboBox* comboBox = new QComboBox(parent);
  1350. comboBox->addItem(tr(s_defaultPolyWidthSizeString)); //size = 0
  1351. for (int i = static_cast<int>(ccCoordinateSystem::MIN_AXIS_WIDTH_F); i <= static_cast<int>(ccCoordinateSystem::MAX_AXIS_WIDTH_F); ++i)
  1352. {
  1353. comboBox->addItem(QString::number(i));
  1354. }
  1355. ccCoordinateSystem* cs = ccHObjectCaster::ToCoordinateSystem(m_currentObject);
  1356. if (cs)
  1357. {
  1358. comboBox->setCurrentIndex(static_cast<int>(cs->getAxisWidth()));
  1359. }
  1360. connect(comboBox, qOverload<int>(&QComboBox::currentIndexChanged),
  1361. this, &ccPropertiesTreeDelegate::coordinateSystemAxisWidthChanged);
  1362. outputWidget = comboBox;
  1363. }
  1364. break;
  1365. case OBJECT_COORDINATE_SYSTEM_DISP_SCALE:
  1366. {
  1367. QDoubleSpinBox* spinBox = new QDoubleSpinBox(parent);
  1368. spinBox->setRange(1.0e-3, 1.0e6);
  1369. spinBox->setDecimals(3);
  1370. spinBox->setSingleStep(1.0e-1);
  1371. ccCoordinateSystem* cs = ccHObjectCaster::ToCoordinateSystem(m_currentObject);
  1372. if (cs)
  1373. {
  1374. spinBox->setValue(cs->getDisplayScale());
  1375. }
  1376. connect(spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
  1377. this, &ccPropertiesTreeDelegate::coordinateSystemDisplayScaleChanged);
  1378. outputWidget = spinBox;
  1379. }
  1380. break;
  1381. case OBJECT_CLOUD_NORMAL_COLOR:
  1382. {
  1383. QComboBox *comboBox = new QComboBox(parent);
  1384. comboBox->addItem("Yellow");
  1385. comboBox->addItem("Red");
  1386. comboBox->addItem("Green");
  1387. comboBox->addItem("Blue");
  1388. comboBox->addItem("Black");
  1389. connect(comboBox, qOverload<int>(&QComboBox::currentIndexChanged),
  1390. this, &ccPropertiesTreeDelegate::normalColorChanged);
  1391. outputWidget = comboBox;
  1392. }
  1393. break;
  1394. case OBJECT_CLOUD_NORMAL_LENGTH:
  1395. {
  1396. QDoubleSpinBox *spinBox = new QDoubleSpinBox(parent);
  1397. spinBox->setRange(ccColorScale::MIN_STEPS, ccColorScale::MAX_STEPS);
  1398. spinBox->setSingleStep(0.1);
  1399. spinBox->setMinimum(0);
  1400. connect(spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
  1401. this, &ccPropertiesTreeDelegate::normalLengthChanged);
  1402. outputWidget = spinBox;
  1403. }
  1404. break;
  1405. default:
  1406. return QStyledItemDelegate::createEditor(parent, option, index);
  1407. }
  1408. if (outputWidget)
  1409. {
  1410. outputWidget->setFocusPolicy(Qt::StrongFocus); //Qt doc: << The returned editor widget should have Qt::StrongFocus >>
  1411. outputWidget->installEventFilter(new FilterMouseWheelNoFocusEvent(outputWidget));
  1412. if (m_lastFocusItemRole == itemData)
  1413. {
  1414. outputWidget->setFocus(Qt::MouseFocusReason);
  1415. }
  1416. }
  1417. else
  1418. {
  1419. //shouldn't happen
  1420. assert(false);
  1421. }
  1422. return outputWidget;
  1423. }
  1424. void ccPropertiesTreeDelegate::updateEditorGeometry(QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index) const
  1425. {
  1426. QStyledItemDelegate::updateEditorGeometry(editor, option, index);
  1427. if (!m_model || !editor)
  1428. {
  1429. return;
  1430. }
  1431. QStandardItem* item = m_model->itemFromIndex(index);
  1432. if (item && item->data().isValid() && item->column() == 0)
  1433. {
  1434. if (isWideEditor(item->data().toInt()))
  1435. {
  1436. QWidget* widget = qobject_cast<QWidget*>(editor);
  1437. if (!widget)
  1438. {
  1439. return;
  1440. }
  1441. //we must resize the SF edit widget so that it spans on both columns!
  1442. QRect rect = m_view->visualRect(m_model->index(item->row(), 1)); //second column width
  1443. widget->resize(option.rect.width() + rect.width(), widget->height());
  1444. }
  1445. }
  1446. }
  1447. void SetDoubleSpinBoxValue(QWidget *editor, double value, bool keyboardTracking = false)
  1448. {
  1449. QDoubleSpinBox* spinBox = qobject_cast<QDoubleSpinBox*>(editor);
  1450. if (!spinBox)
  1451. {
  1452. assert(false);
  1453. return;
  1454. }
  1455. spinBox->setKeyboardTracking(keyboardTracking);
  1456. spinBox->setValue(value);
  1457. }
  1458. void SetSpinBoxValue(QWidget *editor, int value, bool keyboardTracking = false)
  1459. {
  1460. QSpinBox* spinBox = qobject_cast<QSpinBox*>(editor);
  1461. if (!spinBox)
  1462. {
  1463. assert(false);
  1464. return;
  1465. }
  1466. spinBox->setKeyboardTracking(keyboardTracking);
  1467. spinBox->setValue(value);
  1468. }
  1469. void SetComboBoxIndex(QWidget *editor, int index)
  1470. {
  1471. QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
  1472. if (!comboBox)
  1473. {
  1474. assert(false);
  1475. return;
  1476. }
  1477. assert(index < 0 || index < comboBox->maxCount());
  1478. comboBox->setCurrentIndex(index);
  1479. }
  1480. void ccPropertiesTreeDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
  1481. {
  1482. if (!m_model || !m_currentObject)
  1483. return;
  1484. QStandardItem* item = m_model->itemFromIndex(index);
  1485. if (!item || !item->data().isValid() || (item->column() == 0 && !isWideEditor(item->data().toInt())))
  1486. return;
  1487. switch (item->data().toInt())
  1488. {
  1489. case OBJECT_CURRENT_DISPLAY:
  1490. {
  1491. QComboBox *comboBox = qobject_cast<QComboBox*>(editor);
  1492. if (!comboBox)
  1493. {
  1494. assert(false);
  1495. return;
  1496. }
  1497. ccGLWindowInterface* win = static_cast<ccGLWindowInterface*>(m_currentObject->getDisplay());
  1498. int pos = (win ? comboBox->findText(win->getWindowTitle()) : 0);
  1499. comboBox->setCurrentIndex(std::max(pos, 0)); //0 = "NONE"
  1500. break;
  1501. }
  1502. case OBJECT_CURRENT_SCALAR_FIELD:
  1503. {
  1504. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  1505. assert(cloud);
  1506. if (!cloud)
  1507. {
  1508. return;
  1509. }
  1510. int pos = cloud->getCurrentDisplayedScalarFieldIndex();
  1511. SetComboBoxIndex(editor, pos + 1);
  1512. break;
  1513. }
  1514. case OBJECT_CURRENT_COLOR_RAMP:
  1515. {
  1516. QFrame *selectorFrame = qobject_cast<QFrame*>(editor);
  1517. if (!selectorFrame)
  1518. {
  1519. return;
  1520. }
  1521. ccColorScaleSelector* selector = static_cast<ccColorScaleSelector*>(selectorFrame);
  1522. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  1523. assert(cloud);
  1524. if (!cloud)
  1525. {
  1526. return;
  1527. }
  1528. ccScalarField* sf = cloud->getCurrentDisplayedScalarField();
  1529. if (sf)
  1530. {
  1531. if (sf->getColorScale())
  1532. {
  1533. selector->setSelectedScale(sf->getColorScale()->getUuid());
  1534. }
  1535. else
  1536. {
  1537. selector->setSelectedScale(QString());
  1538. }
  1539. }
  1540. break;
  1541. }
  1542. case OBJECT_COLOR_RAMP_STEPS:
  1543. {
  1544. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  1545. assert(cloud);
  1546. ccScalarField* sf = cloud ? cloud->getCurrentDisplayedScalarField() : nullptr;
  1547. if (sf)
  1548. SetSpinBoxValue(editor, sf->getColorRampSteps(), true);
  1549. break;
  1550. }
  1551. case OBJECT_CLOUD_SF_EDITOR:
  1552. {
  1553. sfEditDlg *sfd = qobject_cast<sfEditDlg*>(editor);
  1554. if (!sfd)
  1555. {
  1556. return;
  1557. }
  1558. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  1559. assert(cloud);
  1560. ccScalarField* sf = cloud->getCurrentDisplayedScalarField();
  1561. if (sf)
  1562. {
  1563. sfd->fillDialogWith(sf);
  1564. }
  1565. break;
  1566. }
  1567. case OBJECT_HISTORY_MATRIX_EDITOR:
  1568. {
  1569. MatrixDisplayDlg *mdd = qobject_cast<MatrixDisplayDlg*>(editor);
  1570. if (!mdd)
  1571. {
  1572. return;
  1573. }
  1574. mdd->fillDialogWith(m_currentObject->getGLTransformationHistory());
  1575. break;
  1576. }
  1577. case OBJECT_GLTRANS_MATRIX_EDITOR:
  1578. {
  1579. MatrixDisplayDlg *mdd = qobject_cast<MatrixDisplayDlg*>(editor);
  1580. if (!mdd)
  1581. {
  1582. return;
  1583. }
  1584. mdd->fillDialogWith(m_currentObject->getGLTransformation());
  1585. break;
  1586. }
  1587. case OBJECT_SENSOR_MATRIX_EDITOR:
  1588. {
  1589. MatrixDisplayDlg* mdd = qobject_cast<MatrixDisplayDlg*>(editor);
  1590. if (!mdd)
  1591. {
  1592. return;
  1593. }
  1594. ccSensor* sensor = ccHObjectCaster::ToSensor(m_currentObject);
  1595. assert(sensor);
  1596. if (!sensor)
  1597. {
  1598. return;
  1599. }
  1600. ccIndexedTransformation trans;
  1601. if (sensor->getActiveAbsoluteTransformation(trans))
  1602. {
  1603. mdd->fillDialogWith(trans);
  1604. }
  1605. else
  1606. {
  1607. mdd->clear();
  1608. mdd->setEnabled(false);
  1609. }
  1610. break;
  1611. }
  1612. case TREE_VIEW_HEADER:
  1613. {
  1614. QLabel* label = qobject_cast<QLabel*>(editor);
  1615. if (label)
  1616. {
  1617. label->setText(item->accessibleDescription());
  1618. }
  1619. break;
  1620. }
  1621. case OBJECT_OCTREE_TYPE:
  1622. {
  1623. ccOctree* octree = ccHObjectCaster::ToOctree(m_currentObject);
  1624. assert(octree);
  1625. SetComboBoxIndex(editor, static_cast<int>(octree->getDisplayMode()));
  1626. break;
  1627. }
  1628. case OBJECT_OCTREE_LEVEL:
  1629. {
  1630. ccOctree* octree = ccHObjectCaster::ToOctree(m_currentObject);
  1631. assert(octree);
  1632. SetSpinBoxValue(editor, octree ? octree->getDisplayedLevel() : 0);
  1633. break;
  1634. }
  1635. case OBJECT_PRIMITIVE_PRECISION:
  1636. {
  1637. ccGenericPrimitive* primitive = ccHObjectCaster::ToPrimitive(m_currentObject);
  1638. assert(primitive);
  1639. SetSpinBoxValue(editor, primitive ? primitive->getDrawingPrecision() : 0);
  1640. break;
  1641. }
  1642. case OBJECT_SPHERE_RADIUS:
  1643. {
  1644. ccSphere* sphere = ccHObjectCaster::ToSphere(m_currentObject);
  1645. assert(sphere);
  1646. SetDoubleSpinBoxValue(editor, sphere ? sphere->getRadius() : 0.0);
  1647. break;
  1648. }
  1649. case OBJECT_CONE_HEIGHT:
  1650. {
  1651. ccCone* cone = ccHObjectCaster::ToCone(m_currentObject);
  1652. assert(cone);
  1653. SetDoubleSpinBoxValue(editor, cone ? cone->getHeight() : 0.0);
  1654. break;
  1655. }
  1656. case OBJECT_CONE_BOTTOM_RADIUS:
  1657. {
  1658. ccCone* cone = ccHObjectCaster::ToCone(m_currentObject);
  1659. assert(cone);
  1660. SetDoubleSpinBoxValue(editor, cone ? cone->getBottomRadius() : 0.0);
  1661. break;
  1662. }
  1663. case OBJECT_CONE_TOP_RADIUS:
  1664. {
  1665. ccCone* cone = ccHObjectCaster::ToCone(m_currentObject);
  1666. assert(cone);
  1667. SetDoubleSpinBoxValue(editor, cone ? cone->getTopRadius() : 0.0);
  1668. break;
  1669. }
  1670. case OBJECT_IMAGE_ALPHA:
  1671. {
  1672. QSlider *slider = qobject_cast<QSlider*>(editor);
  1673. if (!slider)
  1674. {
  1675. return;
  1676. }
  1677. ccImage* image = ccHObjectCaster::ToImage(m_currentObject);
  1678. assert(image);
  1679. if (!image)
  1680. {
  1681. return;
  1682. }
  1683. slider->setValue(static_cast<int>(image->getAlpha()*255.0f));
  1684. //slider->setTickPosition(QSlider::NoTicks);
  1685. break;
  1686. }
  1687. case OBJECT_SENSOR_INDEX:
  1688. {
  1689. ccSensor* sensor = ccHObjectCaster::ToSensor(m_currentObject);
  1690. assert(sensor);
  1691. SetDoubleSpinBoxValue(editor, sensor ? sensor->getActiveIndex() : 0.0);
  1692. break;
  1693. }
  1694. case OBJECT_SENSOR_UNCERTAINTY:
  1695. {
  1696. QLineEdit *lineEdit = qobject_cast<QLineEdit*>(editor);
  1697. if (!lineEdit)
  1698. {
  1699. return;
  1700. }
  1701. ccGBLSensor* sensor = ccHObjectCaster::ToGBLSensor(m_currentObject);
  1702. assert(sensor);
  1703. lineEdit->setText(QString::number(sensor ? sensor->getUncertainty() : 0, 'g', 8));
  1704. break;
  1705. }
  1706. case OBJECT_SENSOR_DISPLAY_SCALE:
  1707. {
  1708. ccSensor* sensor = ccHObjectCaster::ToSensor(m_currentObject);
  1709. assert(sensor);
  1710. SetDoubleSpinBoxValue(editor, sensor ? sensor->getGraphicScale() : 0.0);
  1711. break;
  1712. }
  1713. case OBJECT_TRANS_BUFFER_TRIHDERONS_SCALE:
  1714. {
  1715. ccIndexedTransformationBuffer* buffer = ccHObjectCaster::ToTransBuffer(m_currentObject);
  1716. assert(buffer);
  1717. SetDoubleSpinBoxValue(editor, buffer ? buffer->trihedronsDisplayScale() : 0.0);
  1718. break;
  1719. }
  1720. case OBJECT_CLOUD_POINT_SIZE:
  1721. {
  1722. ccGenericPointCloud* cloud = ccHObjectCaster::ToGenericPointCloud(m_currentObject);
  1723. assert(cloud);
  1724. if (!cloud)
  1725. {
  1726. return;
  1727. }
  1728. SetComboBoxIndex(editor, static_cast<int>(cloud->getPointSize()));
  1729. break;
  1730. }
  1731. case OBJECT_POLYLINE_WIDTH:
  1732. {
  1733. ccPolyline* poly = ccHObjectCaster::ToPolyline(m_currentObject);
  1734. assert(poly);
  1735. if (!poly)
  1736. {
  1737. return;
  1738. }
  1739. SetComboBoxIndex(editor, static_cast<int>(poly->getWidth()));
  1740. break;
  1741. }
  1742. case OBJECT_COLOR_SOURCE:
  1743. {
  1744. int currentIndex = 0; //no color
  1745. int lastIndex = currentIndex;
  1746. if (m_currentObject->hasColors())
  1747. {
  1748. ++lastIndex;
  1749. if (m_currentObject->colorsShown())
  1750. {
  1751. currentIndex = lastIndex;
  1752. }
  1753. }
  1754. if (m_currentObject->hasScalarFields())
  1755. {
  1756. ++lastIndex;
  1757. if (m_currentObject->sfShown())
  1758. {
  1759. currentIndex = lastIndex;
  1760. }
  1761. }
  1762. SetComboBoxIndex(editor, currentIndex);
  1763. break;
  1764. }
  1765. case OBJECT_CLOUD_NORMAL_COLOR:
  1766. {
  1767. ccGenericPointCloud* cloud = ccHObjectCaster::ToGenericPointCloud(m_currentObject);
  1768. assert(cloud);
  1769. if (!cloud)
  1770. {
  1771. return;
  1772. }
  1773. SetComboBoxIndex(editor, static_cast<ccPointCloud*>(cloud)->getNormalLineColor());
  1774. break;
  1775. }
  1776. case OBJECT_CLOUD_NORMAL_LENGTH:
  1777. {
  1778. ccGenericPointCloud* cloud = ccHObjectCaster::ToGenericPointCloud(m_currentObject);
  1779. assert(cloud);
  1780. if (!cloud)
  1781. {
  1782. return;
  1783. }
  1784. SetDoubleSpinBoxValue(editor, static_cast<ccPointCloud*>(cloud)->getNormalLength());
  1785. break;
  1786. }
  1787. default:
  1788. QStyledItemDelegate::setEditorData(editor, index);
  1789. break;
  1790. }
  1791. }
  1792. void ccPropertiesTreeDelegate::updateItem(QStandardItem * item)
  1793. {
  1794. if (!m_currentObject || item->column() == 0 || !item->data().isValid())
  1795. return;
  1796. bool redraw = false;
  1797. switch (item->data().toInt())
  1798. {
  1799. case OBJECT_NAME:
  1800. m_currentObject->setName(item->text());
  1801. Q_EMIT ccObjectPropertiesChanged(m_currentObject);
  1802. break;
  1803. case OBJECT_VISIBILITY:
  1804. {
  1805. bool objectWasDisplayed = m_currentObject->isDisplayed();
  1806. m_currentObject->setVisible(item->checkState() == Qt::Checked);
  1807. bool objectIsDisplayed = m_currentObject->isDisplayed();
  1808. if (objectWasDisplayed != objectIsDisplayed)
  1809. {
  1810. if (m_currentObject->isGroup())
  1811. Q_EMIT ccObjectAndChildrenAppearanceChanged(m_currentObject);
  1812. else
  1813. Q_EMIT ccObjectAppearanceChanged(m_currentObject);
  1814. }
  1815. }
  1816. break;
  1817. case OBJECT_NORMALS_SHOWN:
  1818. m_currentObject->showNormals(item->checkState() == Qt::Checked);
  1819. redraw = true;
  1820. break;
  1821. case OBJECT_MATERIALS:
  1822. {
  1823. ccGenericMesh* mesh = ccHObjectCaster::ToGenericMesh(m_currentObject);
  1824. assert(mesh);
  1825. mesh->showMaterials(item->checkState() == Qt::Checked);
  1826. }
  1827. redraw = true;
  1828. break;
  1829. case OBJECT_SF_SHOW_SCALE:
  1830. {
  1831. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  1832. assert(cloud);
  1833. cloud->showSFColorsScale(item->checkState() == Qt::Checked);
  1834. }
  1835. redraw = true;
  1836. break;
  1837. case OBJECT_COORDINATE_SYSTEM_DISP_AXES:
  1838. {
  1839. ccCoordinateSystem* cs = ccHObjectCaster::ToCoordinateSystem(m_currentObject);
  1840. if (cs)
  1841. {
  1842. cs->showAxisLines(item->checkState() == Qt::Checked);
  1843. }
  1844. }
  1845. redraw = true;
  1846. break;
  1847. case OBJECT_COORDINATE_SYSTEM_DISP_PLANES:
  1848. {
  1849. ccCoordinateSystem* cs = ccHObjectCaster::ToCoordinateSystem(m_currentObject);
  1850. if (cs)
  1851. {
  1852. cs->showAxisPlanes(item->checkState() == Qt::Checked);
  1853. }
  1854. }
  1855. redraw = true;
  1856. break;
  1857. case OBJECT_FACET_CONTOUR:
  1858. {
  1859. ccFacet* facet = ccHObjectCaster::ToFacet(m_currentObject);
  1860. assert(facet);
  1861. if (facet && facet->getContour())
  1862. facet->getContour()->setVisible(item->checkState() == Qt::Checked);
  1863. }
  1864. redraw = true;
  1865. break;
  1866. case OBJECT_FACET_MESH:
  1867. {
  1868. ccFacet* facet = ccHObjectCaster::ToFacet(m_currentObject);
  1869. assert(facet);
  1870. if (facet && facet->getPolygon())
  1871. facet->getPolygon()->setVisible(item->checkState() == Qt::Checked);
  1872. }
  1873. redraw = true;
  1874. break;
  1875. case OBJECT_PLANE_NORMAL_VECTOR:
  1876. {
  1877. ccPlanarEntityInterface* plane = ccHObjectCaster::ToPlanarEntity(m_currentObject);
  1878. assert(plane);
  1879. if (plane)
  1880. plane->showNormalVector(item->checkState() == Qt::Checked);
  1881. }
  1882. redraw = true;
  1883. break;
  1884. case OBJECT_MESH_WIRE:
  1885. {
  1886. ccGenericMesh* mesh = ccHObjectCaster::ToGenericMesh(m_currentObject);
  1887. assert(mesh);
  1888. mesh->showWired(item->checkState() == Qt::Checked);
  1889. }
  1890. redraw = true;
  1891. break;
  1892. case OBJECT_MESH_STIPPLING:
  1893. {
  1894. ccGenericMesh* mesh = ccHObjectCaster::ToGenericMesh(m_currentObject);
  1895. assert(mesh);
  1896. mesh->enableStippling(item->checkState() == Qt::Checked);
  1897. }
  1898. redraw = true;
  1899. break;
  1900. case OBJECT_LABEL_DISP_2D:
  1901. {
  1902. cc2DLabel* label = ccHObjectCaster::To2DLabel(m_currentObject);
  1903. assert(label);
  1904. label->setDisplayedIn2D(item->checkState() == Qt::Checked);
  1905. }
  1906. redraw = true;
  1907. break;
  1908. case OBJECT_LABEL_POINT_LEGEND:
  1909. {
  1910. cc2DLabel* label = ccHObjectCaster::To2DLabel(m_currentObject);
  1911. assert(label);
  1912. label->displayPointLegend(item->checkState() == Qt::Checked);
  1913. }
  1914. redraw = true;
  1915. break;
  1916. case OBJECT_NAME_IN_3D:
  1917. m_currentObject->showNameIn3D(item->checkState() == Qt::Checked);
  1918. redraw = true;
  1919. break;
  1920. case OBJECT_SHOW_TRANS_BUFFER_PATH:
  1921. {
  1922. ccIndexedTransformationBuffer* buffer = ccHObjectCaster::ToTransBuffer(m_currentObject);
  1923. assert(buffer);
  1924. buffer->showPathAsPolyline(item->checkState() == Qt::Checked);
  1925. }
  1926. redraw = true;
  1927. break;
  1928. case OBJECT_SHOW_TRANS_BUFFER_TRIHDERONS:
  1929. {
  1930. ccIndexedTransformationBuffer* buffer = ccHObjectCaster::ToTransBuffer(m_currentObject);
  1931. assert(buffer);
  1932. buffer->showTrihedrons(item->checkState() == Qt::Checked);
  1933. }
  1934. redraw = true;
  1935. break;
  1936. case OBJECT_SENSOR_DRAW_FRUSTUM:
  1937. {
  1938. ccCameraSensor* sensor = ccHObjectCaster::ToCameraSensor(m_currentObject);
  1939. sensor->drawFrustum(item->checkState() == Qt::Checked);
  1940. }
  1941. redraw = true;
  1942. break;
  1943. case OBJECT_SENSOR_DRAW_FRUSTUM_PLANES:
  1944. {
  1945. ccCameraSensor* sensor = ccHObjectCaster::ToCameraSensor(m_currentObject);
  1946. sensor->drawFrustumPlanes(item->checkState() == Qt::Checked);
  1947. }
  1948. redraw = true;
  1949. break;
  1950. case OBJECT_CLOUD_DRAW_NORMALS:
  1951. {
  1952. ccGenericPointCloud* cloud = ccHObjectCaster::ToGenericPointCloud(m_currentObject);
  1953. bool isChecked = (item->checkState() == Qt::Checked);
  1954. if (cloud)
  1955. {
  1956. static_cast<ccPointCloud*>(cloud)->showNormalsAsLines(isChecked);
  1957. }
  1958. }
  1959. redraw = true;
  1960. break;
  1961. }
  1962. if (redraw)
  1963. {
  1964. updateDisplay();
  1965. }
  1966. }
  1967. void ccPropertiesTreeDelegate::updateDisplay()
  1968. {
  1969. ccHObject* object = m_currentObject;
  1970. if (!object)
  1971. {
  1972. return;
  1973. }
  1974. bool objectIsDisplayed = object->isDisplayed();
  1975. if (!objectIsDisplayed)
  1976. {
  1977. //DGM: point clouds may be mesh vertices of meshes which may depend on several of their parameters
  1978. if (object->isKindOf(CC_TYPES::POINT_CLOUD))
  1979. {
  1980. ccHObject* parent = object->getParent();
  1981. if (parent && parent->isKindOf(CC_TYPES::MESH) && parent->isDisplayed()) //specific case: vertices
  1982. {
  1983. object = parent;
  1984. objectIsDisplayed = true;
  1985. }
  1986. }
  1987. // Allows show name toggle on normally non-visible objects to update the screen
  1988. else if (object->isKindOf(CC_TYPES::HIERARCHY_OBJECT))
  1989. {
  1990. objectIsDisplayed = true;
  1991. }
  1992. }
  1993. if (objectIsDisplayed)
  1994. {
  1995. if (object->isGroup())
  1996. {
  1997. Q_EMIT ccObjectAndChildrenAppearanceChanged(m_currentObject);
  1998. }
  1999. else
  2000. {
  2001. Q_EMIT ccObjectAppearanceChanged(m_currentObject);
  2002. }
  2003. }
  2004. }
  2005. void ccPropertiesTreeDelegate::updateModel()
  2006. {
  2007. //simply re-fill model!
  2008. fillModel(m_currentObject);
  2009. }
  2010. void ccPropertiesTreeDelegate::scalarFieldChanged(int pos)
  2011. {
  2012. if (!m_currentObject)
  2013. {
  2014. return;
  2015. }
  2016. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  2017. if (cloud && cloud->getCurrentDisplayedScalarFieldIndex() + 1 != pos)
  2018. {
  2019. cloud->setCurrentDisplayedScalarField(pos - 1);
  2020. cloud->showSF(pos > 0);
  2021. updateDisplay();
  2022. //we must also reset the properties display!
  2023. updateModel();
  2024. }
  2025. }
  2026. void ccPropertiesTreeDelegate::spawnColorRampEditor()
  2027. {
  2028. if (!m_currentObject)
  2029. {
  2030. return;
  2031. }
  2032. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  2033. assert(cloud);
  2034. ccScalarField* sf = (cloud ? static_cast<ccScalarField*>(cloud->getCurrentDisplayedScalarField()) : nullptr);
  2035. if (sf)
  2036. {
  2037. ccGLWindowInterface* glWindow = static_cast<ccGLWindowInterface*>(cloud->getDisplay());
  2038. ccColorScaleEditorDialog* editorDialog = new ccColorScaleEditorDialog( ccColorScalesManager::GetUniqueInstance(),
  2039. MainWindow::TheInstance(),
  2040. sf->getColorScale(),
  2041. glWindow ? glWindow->asWidget() : nullptr);
  2042. editorDialog->setAssociatedScalarField(sf);
  2043. if (editorDialog->exec())
  2044. {
  2045. if (editorDialog->getActiveScale())
  2046. {
  2047. sf->setColorScale(editorDialog->getActiveScale());
  2048. updateDisplay();
  2049. }
  2050. //save current scale manager state to persistent settings
  2051. ccColorScalesManager::GetUniqueInstance()->toPersistentSettings();
  2052. updateModel();
  2053. }
  2054. }
  2055. }
  2056. void ccPropertiesTreeDelegate::colorScaleChanged(int pos)
  2057. {
  2058. if (!m_currentObject)
  2059. {
  2060. return;
  2061. }
  2062. if (pos < 0)
  2063. {
  2064. assert(false);
  2065. return;
  2066. }
  2067. ccColorScaleSelector* selector = dynamic_cast<ccColorScaleSelector*>(QObject::sender());
  2068. if (!selector)
  2069. {
  2070. return;
  2071. }
  2072. ccColorScale::Shared colorScale = selector->getScale(pos);
  2073. if (!colorScale)
  2074. {
  2075. ccLog::Error("Internal error: color scale doesn't seem to exist anymore!");
  2076. return;
  2077. }
  2078. //get current SF
  2079. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  2080. assert(cloud);
  2081. ccScalarField* sf = cloud ? static_cast<ccScalarField*>(cloud->getCurrentDisplayedScalarField()) : nullptr;
  2082. if (sf && sf->getColorScale() != colorScale)
  2083. {
  2084. sf->setColorScale(colorScale);
  2085. updateDisplay();
  2086. updateModel();
  2087. }
  2088. }
  2089. void ccPropertiesTreeDelegate::colorRampStepsChanged(int pos)
  2090. {
  2091. if (!m_currentObject)
  2092. {
  2093. return;
  2094. }
  2095. ccPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  2096. assert(cloud);
  2097. if (!cloud)
  2098. {
  2099. return;
  2100. }
  2101. ccScalarField* sf = static_cast<ccScalarField*>(cloud->getCurrentDisplayedScalarField());
  2102. if (sf && sf->getColorRampSteps() != pos)
  2103. {
  2104. sf->setColorRampSteps(pos);
  2105. updateDisplay();
  2106. }
  2107. }
  2108. void ccPropertiesTreeDelegate::octreeDisplayModeChanged(int pos)
  2109. {
  2110. if (!m_currentObject)
  2111. {
  2112. return;
  2113. }
  2114. QComboBox* comboBox = dynamic_cast<QComboBox*>(QObject::sender());
  2115. if (!comboBox)
  2116. {
  2117. return;
  2118. }
  2119. ccOctree* octree = ccHObjectCaster::ToOctree(m_currentObject);
  2120. assert(octree);
  2121. int mode = comboBox->itemData(pos, Qt::UserRole).toInt();
  2122. if (octree && octree->getDisplayMode() != mode)
  2123. {
  2124. octree->setDisplayMode(static_cast<ccOctree::DisplayMode>(mode));
  2125. updateDisplay();
  2126. }
  2127. }
  2128. void ccPropertiesTreeDelegate::octreeDisplayedLevelChanged(int val)
  2129. {
  2130. if (!m_currentObject)
  2131. {
  2132. return;
  2133. }
  2134. ccOctree* octree = ccHObjectCaster::ToOctree(m_currentObject);
  2135. assert(octree);
  2136. if (octree && octree->getDisplayedLevel() != val) //to avoid infinite loops!
  2137. {
  2138. octree->setDisplayedLevel(val);
  2139. updateDisplay();
  2140. //record item role to force the scroll focus (see 'createEditor').
  2141. m_lastFocusItemRole = OBJECT_OCTREE_LEVEL;
  2142. //we must also reset the properties display!
  2143. updateModel();
  2144. }
  2145. }
  2146. void ccPropertiesTreeDelegate::primitivePrecisionChanged(int val)
  2147. {
  2148. if (!m_currentObject)
  2149. {
  2150. return;
  2151. }
  2152. ccGenericPrimitive* primitive = ccHObjectCaster::ToPrimitive(m_currentObject);
  2153. assert(primitive);
  2154. if (primitive->getDrawingPrecision() != static_cast<unsigned int>(val))
  2155. {
  2156. bool wasVisible = primitive->isVisible();
  2157. primitive->setDrawingPrecision(val);
  2158. primitive->setVisible(wasVisible);
  2159. updateDisplay();
  2160. //record item role to force the scroll focus (see 'createEditor').
  2161. m_lastFocusItemRole = OBJECT_PRIMITIVE_PRECISION;
  2162. //we must also reset the properties display!
  2163. updateModel();
  2164. }
  2165. }
  2166. void ccPropertiesTreeDelegate::sphereRadiusChanged(double val)
  2167. {
  2168. if (!m_currentObject)
  2169. return;
  2170. ccSphere* sphere = ccHObjectCaster::ToSphere(m_currentObject);
  2171. assert(sphere);
  2172. if (!sphere)
  2173. return;
  2174. PointCoordinateType radius = static_cast<PointCoordinateType>(val);
  2175. if (sphere->getRadius() != radius)
  2176. {
  2177. bool wasVisible = sphere->isVisible();
  2178. sphere->setRadius(radius);
  2179. sphere->setVisible(wasVisible);
  2180. updateDisplay();
  2181. //record item role to force the scroll focus (see 'createEditor').
  2182. m_lastFocusItemRole = OBJECT_SPHERE_RADIUS;
  2183. //we must also reset the properties display!
  2184. updateModel();
  2185. }
  2186. }
  2187. void ccPropertiesTreeDelegate::coneHeightChanged(double val)
  2188. {
  2189. if (!m_currentObject)
  2190. return;
  2191. ccCone* cone = ccHObjectCaster::ToCone(m_currentObject);
  2192. assert(cone);
  2193. if (!cone)
  2194. return;
  2195. PointCoordinateType height = static_cast<PointCoordinateType>(val);
  2196. if (cone->getHeight() != height)
  2197. {
  2198. bool wasVisible = cone->isVisible();
  2199. cone->setHeight(height);
  2200. cone->setVisible(wasVisible);
  2201. updateDisplay();
  2202. //record item role to force the scroll focus (see 'createEditor').
  2203. m_lastFocusItemRole = OBJECT_CONE_HEIGHT;
  2204. //we must also reset the properties display!
  2205. updateModel();
  2206. }
  2207. }
  2208. void ccPropertiesTreeDelegate::coneBottomRadiusChanged(double val)
  2209. {
  2210. if (!m_currentObject)
  2211. return;
  2212. ccCone* cone = ccHObjectCaster::ToCone(m_currentObject);
  2213. assert(cone);
  2214. if (!cone)
  2215. return;
  2216. PointCoordinateType radius = static_cast<PointCoordinateType>(val);
  2217. if (cone->getBottomRadius() != radius)
  2218. {
  2219. bool wasVisible = cone->isVisible();
  2220. cone->setBottomRadius(radius); //works for both the bottom and top radii for cylinders!
  2221. cone->setVisible(wasVisible);
  2222. updateDisplay();
  2223. //record item role to force the scroll focus (see 'createEditor').
  2224. m_lastFocusItemRole = OBJECT_CONE_BOTTOM_RADIUS;
  2225. //we must also reset the properties display!
  2226. updateModel();
  2227. }
  2228. }
  2229. void ccPropertiesTreeDelegate::coneTopRadiusChanged(double val)
  2230. {
  2231. if (!m_currentObject)
  2232. return;
  2233. ccCone* cone = ccHObjectCaster::ToCone(m_currentObject);
  2234. assert(cone);
  2235. if (!cone)
  2236. return;
  2237. PointCoordinateType radius = static_cast<PointCoordinateType>(val);
  2238. if (cone->getTopRadius() != radius)
  2239. {
  2240. bool wasVisible = cone->isVisible();
  2241. cone->setTopRadius(radius); //works for both the bottom and top radii for cylinders!
  2242. cone->setVisible(wasVisible);
  2243. updateDisplay();
  2244. //record item role to force the scroll focus (see 'createEditor').
  2245. m_lastFocusItemRole = OBJECT_CONE_TOP_RADIUS;
  2246. //we must also reset the properties display!
  2247. updateModel();
  2248. }
  2249. }
  2250. void ccPropertiesTreeDelegate::imageAlphaChanged(int val)
  2251. {
  2252. ccImage* image = ccHObjectCaster::ToImage(m_currentObject);
  2253. assert(image);
  2254. if (!image)
  2255. return;
  2256. float alpha = val / 255.0f;
  2257. if (image && image->getAlpha() != alpha)
  2258. {
  2259. image->setAlpha(alpha);
  2260. updateDisplay();
  2261. }
  2262. }
  2263. void ccPropertiesTreeDelegate::applyImageViewport()
  2264. {
  2265. if (!m_currentObject)
  2266. return;
  2267. ccImage* image = ccHObjectCaster::ToImage(m_currentObject);
  2268. assert(image);
  2269. if (!image)
  2270. return;
  2271. if (image->getAssociatedSensor() && image->getAssociatedSensor()->applyImageViewport(image))
  2272. {
  2273. ccLog::Print("[ApplyImageViewport] Viewport applied");
  2274. }
  2275. }
  2276. void ccPropertiesTreeDelegate::applySensorViewport()
  2277. {
  2278. if (!m_currentObject)
  2279. return;
  2280. ccSensor* sensor = ccHObjectCaster::ToSensor(m_currentObject);
  2281. assert(sensor);
  2282. if (!sensor)
  2283. return;
  2284. if (sensor->applyViewport())
  2285. {
  2286. ccLog::Print("[ApplySensorViewport] Viewport applied");
  2287. }
  2288. }
  2289. void ccPropertiesTreeDelegate::applyLabelViewport()
  2290. {
  2291. if (!m_currentObject)
  2292. return;
  2293. cc2DViewportObject* viewport = ccHObjectCaster::To2DViewportObject(m_currentObject);
  2294. assert(viewport);
  2295. if (!viewport)
  2296. {
  2297. return;
  2298. }
  2299. ccGLWindowInterface* win = MainWindow::GetActiveGLWindow();
  2300. if (!win)
  2301. return;
  2302. win->setViewportParameters(viewport->getParameters());
  2303. win->redraw();
  2304. }
  2305. void ccPropertiesTreeDelegate::updateLabelViewport()
  2306. {
  2307. if (!m_currentObject)
  2308. {
  2309. return;
  2310. }
  2311. cc2DViewportObject* viewport = ccHObjectCaster::To2DViewportObject(m_currentObject);
  2312. assert(viewport);
  2313. if (!viewport)
  2314. {
  2315. return;
  2316. }
  2317. ccGLWindowInterface* win = MainWindow::GetActiveGLWindow();
  2318. if (!win)
  2319. {
  2320. return;
  2321. }
  2322. viewport->setParameters(win->getViewportParameters());
  2323. // Update the custom light position as well
  2324. {
  2325. bool customLightEnabled = win->customLightEnabled();
  2326. CCVector3f customLightPos = win->getCustomLightPosition();
  2327. viewport->setMetaData("CustomLightEnabled", customLightEnabled);
  2328. viewport->setMetaData("CustomLightPosX", customLightPos.x);
  2329. viewport->setMetaData("CustomLightPosY", customLightPos.y);
  2330. viewport->setMetaData("CustomLightPosZ", customLightPos.z);
  2331. }
  2332. ccLog::Print(QString("Viewport '%1' has been updated").arg(viewport->getName()));
  2333. }
  2334. void ccPropertiesTreeDelegate::sensorUncertaintyChanged()
  2335. {
  2336. if (!m_currentObject)
  2337. {
  2338. return;
  2339. }
  2340. QLineEdit* lineEdit = qobject_cast<QLineEdit*>(QObject::sender());
  2341. if (!lineEdit)
  2342. {
  2343. assert(false);
  2344. return;
  2345. }
  2346. ccGBLSensor* sensor = ccHObjectCaster::ToGBLSensor(m_currentObject);
  2347. assert(sensor);
  2348. PointCoordinateType uncertainty = static_cast<PointCoordinateType>(lineEdit->text().toDouble());
  2349. if (sensor && sensor->getUncertainty() != uncertainty)
  2350. {
  2351. sensor->setUncertainty(uncertainty);
  2352. }
  2353. }
  2354. void ccPropertiesTreeDelegate::sensorScaleChanged(double val)
  2355. {
  2356. if (!m_currentObject)
  2357. {
  2358. return;
  2359. }
  2360. ccSensor* sensor = ccHObjectCaster::ToSensor(m_currentObject);
  2361. assert(sensor);
  2362. if (sensor && sensor->getGraphicScale() != static_cast<PointCoordinateType>(val))
  2363. {
  2364. sensor->setGraphicScale(static_cast<PointCoordinateType>(val));
  2365. updateDisplay();
  2366. }
  2367. }
  2368. void ccPropertiesTreeDelegate::coordinateSystemDisplayScaleChanged(double val)
  2369. {
  2370. if (!m_currentObject)
  2371. {
  2372. return;
  2373. }
  2374. ccCoordinateSystem* cs = ccHObjectCaster::ToCoordinateSystem(m_currentObject);
  2375. assert(cs);
  2376. if (cs && cs->getDisplayScale() != static_cast<PointCoordinateType>(val))
  2377. {
  2378. cs->setDisplayScale(static_cast<PointCoordinateType>(val));
  2379. updateDisplay();
  2380. }
  2381. }
  2382. void ccPropertiesTreeDelegate::sensorIndexChanged(double val)
  2383. {
  2384. if (!m_currentObject)
  2385. {
  2386. return;
  2387. }
  2388. ccSensor* sensor = ccHObjectCaster::ToSensor(m_currentObject);
  2389. assert(sensor);
  2390. if (sensor && sensor->getActiveIndex() != val)
  2391. {
  2392. sensor->setActiveIndex(val);
  2393. updateDisplay();
  2394. }
  2395. }
  2396. void ccPropertiesTreeDelegate::trihedronsScaleChanged(double val)
  2397. {
  2398. if (!m_currentObject)
  2399. {
  2400. return;
  2401. }
  2402. ccIndexedTransformationBuffer* buffer = ccHObjectCaster::ToTransBuffer(m_currentObject);
  2403. assert(buffer);
  2404. if (buffer && buffer->trihedronsDisplayScale() != static_cast<float>(val))
  2405. {
  2406. buffer->setTrihedronsDisplayScale(static_cast<float>(val));
  2407. if (buffer->trihedronsShown())
  2408. {
  2409. updateDisplay();
  2410. }
  2411. }
  2412. }
  2413. void ccPropertiesTreeDelegate::normalColorChanged(int colorIdx)
  2414. {
  2415. if (!m_currentObject)
  2416. {
  2417. return;
  2418. }
  2419. ccGenericPointCloud* cloud = ccHObjectCaster::ToGenericPointCloud(m_currentObject);
  2420. assert(cloud);
  2421. if (cloud)
  2422. {
  2423. static_cast<ccPointCloud*>(cloud)->setNormalLineColor(colorIdx);
  2424. cloud->redrawDisplay();
  2425. updateDisplay();
  2426. }
  2427. }
  2428. void ccPropertiesTreeDelegate::normalLengthChanged(double length)
  2429. {
  2430. if (!m_currentObject)
  2431. {
  2432. return;
  2433. }
  2434. ccGenericPointCloud* cloud = ccHObjectCaster::ToPointCloud(m_currentObject);
  2435. assert(cloud);
  2436. if (cloud)
  2437. {
  2438. static_cast<ccPointCloud*>(cloud)->setNormalLength(length);
  2439. cloud->redrawDisplay();
  2440. updateDisplay();
  2441. }
  2442. }
  2443. void ccPropertiesTreeDelegate::cloudPointSizeChanged(int size)
  2444. {
  2445. if (!m_currentObject)
  2446. {
  2447. return;
  2448. }
  2449. ccGenericPointCloud* cloud = ccHObjectCaster::ToGenericPointCloud(m_currentObject);
  2450. assert(cloud);
  2451. if (cloud && cloud->getPointSize() != size)
  2452. {
  2453. cloud->setPointSize(size);
  2454. updateDisplay();
  2455. }
  2456. }
  2457. void ccPropertiesTreeDelegate::polyineWidthChanged(int size)
  2458. {
  2459. if (!m_currentObject)
  2460. {
  2461. return;
  2462. }
  2463. ccPolyline* polyline = ccHObjectCaster::ToPolyline(m_currentObject);
  2464. assert(polyline);
  2465. if (polyline && polyline->getWidth() != static_cast<PointCoordinateType>(size))
  2466. {
  2467. polyline->setWidth(static_cast<PointCoordinateType>(size));
  2468. updateDisplay();
  2469. }
  2470. }
  2471. void ccPropertiesTreeDelegate::coordinateSystemAxisWidthChanged(int size)
  2472. {
  2473. if (!m_currentObject)
  2474. {
  2475. return;
  2476. }
  2477. ccCoordinateSystem* cs = ccHObjectCaster::ToCoordinateSystem(m_currentObject);
  2478. assert(cs);
  2479. if (cs && cs->getAxisWidth() != static_cast<PointCoordinateType>(size))
  2480. {
  2481. cs->setAxisWidth(static_cast<PointCoordinateType>(size));
  2482. updateDisplay();
  2483. }
  2484. }
  2485. void ccPropertiesTreeDelegate::objectDisplayChanged(const QString& newDisplayTitle)
  2486. {
  2487. if (!m_currentObject)
  2488. {
  2489. return;
  2490. }
  2491. QString actualDisplayTitle;
  2492. ccGLWindowInterface* win = static_cast<ccGLWindowInterface*>(m_currentObject->getDisplay());
  2493. if (win)
  2494. {
  2495. actualDisplayTitle = win->getWindowTitle();
  2496. }
  2497. else
  2498. {
  2499. actualDisplayTitle = tr(s_noneString);
  2500. }
  2501. if (actualDisplayTitle != newDisplayTitle)
  2502. {
  2503. //we first mark the "old displays" before removal,
  2504. //to be sure that they will also be redrawn!
  2505. m_currentObject->prepareDisplayForRefresh_recursive();
  2506. ccGLWindowInterface* win = MainWindow::GetGLWindow(newDisplayTitle);
  2507. m_currentObject->setDisplay_recursive(win);
  2508. if (win)
  2509. {
  2510. m_currentObject->prepareDisplayForRefresh_recursive();
  2511. win->zoomGlobal();
  2512. }
  2513. MainWindow::RefreshAllGLWindow(false);
  2514. }
  2515. }
  2516. void ccPropertiesTreeDelegate::colorSourceChanged(const QString & source)
  2517. {
  2518. if (!m_currentObject)
  2519. {
  2520. return;
  2521. }
  2522. bool appearanceChanged = false;
  2523. if (source == tr( s_noneString ))
  2524. {
  2525. appearanceChanged = m_currentObject->colorsShown() || m_currentObject->sfShown();
  2526. m_currentObject->showColors(false);
  2527. m_currentObject->showSF(false);
  2528. }
  2529. else if (source == s_rgbColor)
  2530. {
  2531. appearanceChanged = !m_currentObject->colorsShown() || m_currentObject->sfShown();
  2532. m_currentObject->showColors(true);
  2533. m_currentObject->showSF(false);
  2534. }
  2535. else if (source == tr( s_sfColor ))
  2536. {
  2537. appearanceChanged = m_currentObject->colorsShown() || !m_currentObject->sfShown();
  2538. m_currentObject->showColors(false);
  2539. m_currentObject->showSF(true);
  2540. }
  2541. else
  2542. {
  2543. assert(false);
  2544. }
  2545. if (appearanceChanged)
  2546. {
  2547. updateDisplay();
  2548. }
  2549. }