diff --git a/CMakeLists.txt b/CMakeLists.txt index c4917b45f..e464aa66b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,7 +62,7 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX) include(cMake/ConfigureChecks.cmake) configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) add_definitions(-DHAVE_CONFIG_H) - set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated -Wno-write-strings ${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS "-Wall -Wno-deprecated -Wno-write-strings -std=c++11 ${CMAKE_CXX_FLAGS}") INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) # get linker errors as soon as possible and not at runtime e.g. for modules if(UNIX) diff --git a/FCMasterMerge.kdev4 b/FCMasterMerge.kdev4 new file mode 100644 index 000000000..1aa8760a5 --- /dev/null +++ b/FCMasterMerge.kdev4 @@ -0,0 +1,3 @@ +[Project] +Manager=KDevCMakeManager +Name=FCMasterMerge diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine.jt b/data/tests/Jt/Engine/2_Cylinder_Engine.jt new file mode 100644 index 000000000..e127bf970 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Cam_shaft_123_457_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Cam_shaft_123_457_0_Parts.jt new file mode 100644 index 000000000..62e28de8c Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Cam_shaft_123_457_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Case_r_123_200_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Case_r_123_200_0_Parts.jt new file mode 100644 index 000000000..939b2b8ed Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Case_r_123_200_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Cylinder_1_123_100_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Cylinder_1_123_100_0_Parts.jt new file mode 100644 index 000000000..ec0e43589 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Cylinder_1_123_100_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Cylinder_2_123_101_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Cylinder_2_123_101_0_Parts.jt new file mode 100644 index 000000000..b6e26e7a3 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Cylinder_2_123_101_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Head_1_123_150_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Head_1_123_150_0_Parts.jt new file mode 100644 index 000000000..2eedfeac3 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Head_1_123_150_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Head_2_123_151_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Head_2_123_151_0_Parts.jt new file mode 100644 index 000000000..e49232025 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Head_2_123_151_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Head_Nut_123_005_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Head_Nut_123_005_0_Parts.jt new file mode 100644 index 000000000..7e4bff687 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Head_Nut_123_005_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Head_Stud_123_006_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Head_Stud_123_006_0_Parts.jt new file mode 100644 index 000000000..2ce29b3bd Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Head_Stud_123_006_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Lifter_123_923_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Lifter_123_923_0_Parts.jt new file mode 100644 index 000000000..dc21b8023 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Lifter_123_923_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Piston_123_844_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Piston_123_844_0_Parts.jt new file mode 100644 index 000000000..f48296c86 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Piston_123_844_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Piston_pin_123_845_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Piston_pin_123_845_0_Parts.jt new file mode 100644 index 000000000..d1a794b0c Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Piston_pin_123_845_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Arm_123_600_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Arm_123_600_0_Parts.jt new file mode 100644 index 000000000..119ab63e6 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Arm_123_600_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Arm_Shaft_123_601_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Arm_Shaft_123_601_0_Parts.jt new file mode 100644 index 000000000..4380afdd8 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Arm_Shaft_123_601_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Arm_copy_123_602_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Arm_copy_123_602_0_Parts.jt new file mode 100644 index 000000000..fe3fdceaf Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Arm_copy_123_602_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Bolt_123_603_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Bolt_123_603_0_Parts.jt new file mode 100644 index 000000000..14b1608c3 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Bolt_123_603_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Mount_123_604_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Mount_123_604_0_Parts.jt new file mode 100644 index 000000000..49e3ca8a6 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Mount_123_604_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Mount_Cap_123_608_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Mount_Cap_123_608_0_Parts.jt new file mode 100644 index 000000000..fe5d96def Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Rocker_Mount_Cap_123_608_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Spark_Plug__0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Spark_Plug__0_Parts.jt new file mode 100644 index 000000000..5a54db99a Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Spark_Plug__0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Spring_Link__0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Spring_Link__0_Parts.jt new file mode 100644 index 000000000..3eef013db Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Spring_Link__0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_123_700_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_123_700_0_Parts.jt new file mode 100644 index 000000000..ae47415de Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_123_700_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Cover_123_701_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Cover_123_701_0_Parts.jt new file mode 100644 index 000000000..e86d506fe Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Cover_123_701_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Cover_copy__0_Main.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Cover_copy__0_Main.jt new file mode 100644 index 000000000..2bb2805cd Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Cover_copy__0_Main.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Spring_123_702_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Spring_123_702_0_Parts.jt new file mode 100644 index 000000000..1b7d8d5e5 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Spring_123_702_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Spring_Cap_123_704_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Spring_Cap_123_704_0_Parts.jt new file mode 100644 index 000000000..12373feca Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/Valve_Spring_Cap_123_704_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/cam_gear_123_456_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/cam_gear_123_456_0_Parts.jt new file mode 100644 index 000000000..bf095af22 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/cam_gear_123_456_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/crank_123_782_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/crank_123_782_0_Parts.jt new file mode 100644 index 000000000..b1487fe6d Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/crank_123_782_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/crank_gear_123_783_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/crank_gear_123_783_0_Parts.jt new file mode 100644 index 000000000..04f28aad3 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/crank_gear_123_783_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/cylinder_bolt_pattern__0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/cylinder_bolt_pattern__0_Parts.jt new file mode 100644 index 000000000..cb70c2440 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/cylinder_bolt_pattern__0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine/rod_123_699_0_Parts.jt b/data/tests/Jt/Engine/2_Cylinder_Engine/rod_123_699_0_Parts.jt new file mode 100644 index 000000000..5cc5791a6 Binary files /dev/null and b/data/tests/Jt/Engine/2_Cylinder_Engine/rod_123_699_0_Parts.jt differ diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine1_Internals.plmxml b/data/tests/Jt/Engine/2_Cylinder_Engine1_Internals.plmxml new file mode 100644 index 000000000..0f231b863 --- /dev/null +++ b/data/tests/Jt/Engine/2_Cylinder_Engine1_Internals.plmxml @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +0.9861037135124207 -0.1661308258771896 -1.166810754732375e-015 0 0.1661308258771896 0.9861037135124207 -1.062013085640994e-015 0 1.327029577804367e-015 8.534118465009541e-016 1 0 0.07101806253194809 0.02219301462173462 0.02199999988079071 1 + + +-1 1.10096191110321e-032 -7.293991291219912e-017 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.1368601024150848 0.06445372104644775 0.003820367390289903 1 + + +-1 -1.334063881586189e-008 7.982825511732017e-010 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.294677197933197 0.07397986948490143 0.01617963239550591 1 + + +0.9995650053024292 0.02949320152401924 -7.979323313200837e-010 0 -0.0294931884855032 0.9995650053024292 2.354164085893729e-011 0 -3.085015966644567e-015 2.168479519145078e-015 1 0 -0.0453154630959034 -0.02461725845932961 -0.02632036805152893 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0.1368601024150848 -0.06445372104644775 -0.03617963194847107 1 + + +-1 -1.334063881586189e-008 7.041613514502387e-009 0 -1.003604666278664e-019 -1 1.355268465125744e-016 0 -1.736007260287489e-016 1.355268465125744e-016 1 0 -0.294677197933197 0.07397986948490143 0.0161796361207962 1 + + +0.9995650053024292 0.02949320152401924 -7.038550631222051e-009 0 -0.0294931884855032 0.9995650053024292 2.076799010541919e-010 0 1.57434811062825e-016 -2.681045890006053e-016 1 0 -0.0453154630959034 -0.02461725845932961 -0.02632036432623863 1 + + +0.7071067690849304 -0.7071067690849304 4.055928498874345e-013 0 0.7071067690849304 0.7071067690849304 6.101357784178425e-016 0 -2.872288724139332e-013 2.863660101149607e-013 1 0 0.04717867448925972 -0.0528213270008564 -0.08894477039575577 1 + + +1.214013511940948e-008 -7.440697502580917e-010 1 0 -0.9059386253356934 0.4234090149402618 3.675416633368289e-013 0 -0.4234090149402618 -0.9059386253356934 1.728632428171784e-013 0 -0.03029589354991913 -0.05256131291389465 0.02505522221326828 1 + + +-0.4234090149402618 -0.9059386253356934 1.726649286873036e-013 0 -0.9059386253356934 0.4234090149402618 3.675724817835818e-013 0 -1.214013511940948e-008 7.440699723026967e-010 -1 0 -0.09059386700391769 -0.02437981590628624 -0.04005522653460503 1 + + +-0.5 -0.8660253882408142 -2.979083167524747e-016 0 0.8660253882408142 -0.5 -7.816530680941419e-016 0 5.279772353637604e-016 -6.488226847947026e-016 1 0 0.01809818297624588 -0.06969784200191498 -0.1055598109960556 1 + + +-0.9390942454338074 0.3436597287654877 1.284025318025572e-016 0 -0.3436597883701325 -0.9390941858291626 -6.660528172495127e-016 0 2.47777798279003e-008 -2.063888393522007e-009 1 0 -0.05131101608276367 -0.05052240565419197 0.1075598075985909 1 + + +-0.9390942454338074 0.3436597287654877 3.809448359261655e-016 0 -0.3436597883701325 -0.9390941858291626 -2.583991531420675e-015 0 2.47777798279003e-008 -2.063890391923451e-009 1 0 -0.05131101980805397 -0.05052240565419197 -0.01844018884003162 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1.665474158585312e-008 1.004267005555448e-006 -1 0 -1 -1.666503557373744e-008 -1.665475757306467e-008 0 -1.6665051560949e-008 1 1.004267005555448e-006 0 -0.04826182126998901 -0.05911042168736458 0.03459598124027252 1 + + +1 9.977915303889529e-014 -9.877358024823479e-007 0 -9.946720638254192e-007 -3.500436562831055e-008 -0.9999999403953552 0 -2.75101122437782e-014 1 -2.288952989822068e-013 0 0.02452629990875721 0.2137382179498673 0.2830735743045807 1 + + +0.9999974370002747 -7.939097296238984e-011 -0.002271066652610898 0 9.118318147522016e-016 1 3.807415215490448e-015 0 0.002271073637530208 3.500404588407946e-008 0.9999973773956299 0 -0.0001340909366263077 -0.01299998629838228 0.0001236627285834402 1 + + +-0.9999850392341614 -0.004973083734512329 -0.002270016819238663 0 0.004973071627318859 -0.9999875426292419 1.127185623772675e-005 0 -0.002270089229568839 -4.575558421038295e-008 0.9999972581863403 0 0.0487947128713131 0.7686771750450134 -0.02040251158177853 1 + + +1 -7.424300063618716e-011 1.35305974757749e-010 0 1.276140897124513e-015 0.9999998807907105 4.341043060584901e-016 0 -4.433523059788058e-008 -2.848764957263938e-008 0.9999998211860657 0 -1.748614808505522e-009 -9.381160293031599e-010 -7.228971310446752e-010 1 + + +0.9999973773956299 1.651584646822357e-008 0.002270044526085258 0 -1.669391558323241e-008 0.9999998807907105 1.723048725921217e-008 0 -0.002270088996738195 -4.57557440824985e-008 0.9999972581863403 0 0.04950515553355217 0.3443533480167389 0.07959935814142227 1 + + +0.9999973773956299 1.651585179729409e-008 0.002270044526085258 0 1.669392091230293e-008 -0.9999998807907105 -1.723048725921217e-008 0 0.002270088996738195 4.57557440824985e-008 -0.9999972581863403 0 0.04947110638022423 0.2571229636669159 0.09459931403398514 1 + + +0.9984452724456787 1.914222380605679e-008 -0.05574143305420876 0 -0.05574139580130577 4.472066095217997e-008 -0.9984451532363892 0 -1.669391203051873e-008 1 1.723049436463953e-008 0 0.01820174790918827 0.326738178730011 0.2976770401000977 1 + + +0.9984543323516846 1.913488922866691e-008 -0.05557771772146225 0 -0.05557768046855927 4.472379444564467e-008 -0.998454213142395 0 -1.669391025416189e-008 0.9999998807907105 1.723049436463953e-008 0 0.06816709786653519 0.326738178730011 0.2977887094020844 1 + + +1 -7.424300063618716e-011 1.35305974757749e-010 0 1.276140897124513e-015 0.9999998807907105 4.341043060584901e-016 0 -4.433523059788058e-008 -2.848764957263938e-008 0.9999998211860657 0 -4.064914627122107e-009 -1.459414988858043e-008 -0.09999953210353851 1 + + +0.9999974370002747 1.662746029751361e-008 0.002270044526085258 0 -1.669391735958925e-008 1.00000011920929 1.723049081192585e-008 0 -0.002270061522722244 -2.438619972622291e-008 0.9999974966049194 0 0.04973216727375984 0.3443534076213837 0.07959914952516556 1 + + +0.9999974370002747 1.662746562658413e-008 0.002270044526085258 0 1.669392268865977e-008 -1.00000011920929 -1.723049081192585e-008 0 0.002270061522722244 2.438619972622291e-008 -0.9999974966049194 0 0.0496981143951416 0.2571230232715607 0.09459911286830902 1 + + +0.9986630082130432 1.791910797521723e-008 -0.05169311910867691 0 -0.05169309675693512 2.345346850063379e-008 -0.998663067817688 0 -1.669391025416189e-008 1.00000011920929 1.72305067991374e-008 0 0.01757495850324631 0.3267382085323334 0.2976291477680206 1 + + +0.9986716508865356 1.791518755567267e-008 -0.05152621492743492 0 -0.05152619630098343 2.345645455648082e-008 -0.9986717104911804 0 -1.669391025416189e-008 1.00000011920929 1.723049791735321e-008 0 0.06753963232040405 0.3267382085323334 0.2977406084537506 1 + + +-0.9999873042106628 -0.004487393889576197 -0.00227002170868218 0 0.004487383179366589 -0.9999898076057434 1.016931855701841e-005 0 -0.002270088996738195 -4.575493051106605e-008 0.9999972581863403 0 -0.02998023852705956 0.7686992287635803 -0.02058133110404015 1 + + +-0.821344792842865 -0.3829995691776276 0.4227339625358582 0 -0.3831273019313812 -0.1786547750234604 -0.9062537550926209 0 0.4226182997226715 -0.9063078165054321 -4.468796817036491e-007 0 -0.2707940638065338 0.1454340070486069 0.1220441088080406 1 + + +0.4546822905540466 0.654166042804718 0.6044259667396545 0 -0.8696395754814148 0.4726209938526154 0.1426760256290436 0 -0.1923305839300156 -0.5905050039291382 0.7837809920310974 0 0.09187051653862 0.08063256740570068 0.1662608832120895 1 + + +0.7850326299667358 0.06081443279981613 -0.6164620518684387 0 -0.1356190741062164 0.9878997206687927 -0.07524674385786057 0 0.6044265031814575 0.1426751911640167 0.7837809920310974 0 -0.001248535001650453 -0.2500619888305664 -0.09022713452577591 1 + + +0.7850326299667358 0.06081448495388031 -0.6164620518684387 0 -0.3924773633480072 -0.7211050391197205 -0.5709372162818909 0 -0.4792551398277283 0.6901518106460571 -0.5422225594520569 0 0.0455969013273716 0.2435131669044495 0.06938881427049637 1 + + +1 -3.002940829333056e-008 3.437022044749938e-008 0 -4.150651022882812e-008 1.000000238418579 4.017514854126603e-008 0 3.73510147255729e-008 2.773385787691041e-008 1 0 -1.489124112907803e-008 -4.276215381793236e-009 1.08718030134014e-008 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1410751193761826 0.09142301231622696 -0.3314632773399353 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.05227819457650185 0.07644443958997726 -0.1796288043260574 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1347948610782623 0.09093648940324783 -0.3265315294265747 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.05855846777558327 0.07595790922641754 -0.1746970862150192 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1285146176815033 0.0904499888420105 -0.3215998709201813 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.0648387148976326 0.07547140121459961 -0.1697653979063034 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1222343519330025 0.08996346592903137 -0.3166681826114655 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.07111898809671402 0.07498487830162048 -0.1648336797952652 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1159540787339211 0.08947695046663284 -0.3117364346981049 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.07739924639463425 0.07449836283922195 -0.1599020063877106 1 + + +-0.4546823501586914 0.6541661024093628 -0.6044260263442993 0 0.8696396350860596 0.4726210236549377 -0.1426760405302048 0 0.192330613732338 -0.5905051231384277 -0.7837811708450317 0 0.01489819493144751 0.08582951128482819 -0.04803464561700821 1 + + +1 2.298901691233368e-008 -2.432995493961698e-008 0 -3.89851670945518e-008 0.9999998807907105 -1.280528216796029e-008 0 -3.000558379540053e-008 -2.485903749516183e-008 0.9999998807907105 0 -1.494453005790319e-009 -7.655864275868396e-010 -5.496130661697407e-009 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1413719058036804 0.08810769766569138 -0.3271084725856781 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.05524870008230209 0.07287602126598358 -0.1727083474397659 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1366616934537888 0.08774281293153763 -0.3234097063541412 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.05995889753103256 0.07251112163066864 -0.1690095812082291 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1319515109062195 0.08737793564796448 -0.3197109401226044 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.06466909497976303 0.07214623689651489 -0.165310800075531 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.127241313457489 0.08701304346323013 -0.3160121440887451 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.0693792924284935 0.07178134471178055 -0.1616120338439941 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1225311160087585 0.08664815127849579 -0.3123133778572083 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.07408948242664337 0.0714164674282074 -0.1579132527112961 1 + + +0.7850325107574463 0.06081444025039673 -0.6164620518684387 0 -0.135619044303894 0.9878994226455689 -0.07524680346250534 0 0.6044264435768127 0.1426751613616943 0.7837807536125183 0 -0.005746716633439064 -0.250409871339798 -0.08668788522481918 1 + + +0.7850325703620911 0.06081447005271912 -0.6164620518684387 0 -0.3681581914424896 -0.7545340657234192 -0.543265700340271 0 -0.498180091381073 0.6534368991851807 -0.5699445009231567 0 0.03418708592653275 0.2526659965515137 0.06506367027759552 1 + + +0.9026297330856323 0.4304179251194 -9.149687798526429e-007 0 -0.4304179251194 0.9026297330856323 4.554329109396349e-007 0 1.028840756589489e-006 1.773579327846164e-008 0.9999999403953552 0 0.2777610719203949 0.5800805687904358 -0.005389846861362457 1 + + +0.9026297926902771 -0.4304177463054657 -9.298340728491894e-007 0 0.4304177463054657 0.9026297926902771 -4.242589284331189e-007 0 1.028840756589489e-006 1.773579505481848e-008 0.9999999403953552 0 0.3539793193340302 0.3309040069580078 -0.005389927886426449 1 + + +-0.8213930130004883 0.3830220103263855 0.4226199984550476 0 -0.3830239772796631 0.1786065548658371 -0.9063069224357605 0 -0.4226182103157044 -0.9063078165054321 4.008188341231289e-007 0 -0.141640841960907 0.3886727094650269 0.1220077648758888 1 + + +-0.9861037135124207 0.1661308258771896 1.702963710921711e-016 0 -0.1661308258771896 -0.9861037135124207 -3.509013978502231e-016 0 1.096343463342109e-016 -3.743166442952229e-016 1 0 -0.07101806253194809 -0.02219301089644432 -0.01999999769032002 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine2_Externals.plmxml b/data/tests/Jt/Engine/2_Cylinder_Engine2_Externals.plmxml new file mode 100644 index 000000000..7567afe10 --- /dev/null +++ b/data/tests/Jt/Engine/2_Cylinder_Engine2_Externals.plmxml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999868869782 0.1321395188570023 -0.003983345814049244 1 + + +2.757793993168889e-013 4.575816179956671e-013 1 0 4.575816179956671e-013 -1 4.575816179956671e-013 0 1 4.575816179956671e-013 -2.757793993168889e-013 0 0.1000000014901161 -0.1338488310575485 0.05437212437391281 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1 -5.031413063960599e-009 -1.553538520049358e-009 0 1.553538409027055e-009 -1.993428355717697e-008 1 0 -5.031413063960599e-009 -1 -1.993428355717697e-008 0 0.1269356608390808 -5.273894387869405e-008 -0.0365588441491127 1 + + +-1 -1.490642098644912e-008 -1.665472915135524e-008 0 1.665472915135524e-008 -1.764261092773722e-008 -1 0 1.490642098644912e-008 -1 1.764261092773722e-008 0 -0.1269356608390808 3.299700068737366e-009 0.0365588404238224 1 + + +2.459232373297482e-009 0.7071067690849304 -0.7071067690849304 0 -4.656259378066352e-009 -0.7071067690849304 -0.7071067690849304 0 -1 5.031412619871389e-009 1.55353274688963e-009 0 0.06499999761581421 0.1287170201539993 -0.003270523622632027 1 + + +-1.553133399667672e-009 5.031413063960599e-009 -1 0 5.031413063960599e-009 1 5.031413063960599e-009 0 1 -5.031413063960599e-009 -1.553133399667672e-009 0 0.2239999920129776 0.03048792481422424 0.02500873245298863 1 + + +1.665474158585312e-008 1.004267005555448e-006 -1 0 -1 -1.666503557373744e-008 -1.665475757306467e-008 0 -1.6665051560949e-008 1 1.004267005555448e-006 0 -0.04826182126998901 -0.05911042168736458 0.03459598124027252 1 + + +1 9.947598300641403e-014 -1.004267005555448e-006 0 1.011203266898519e-006 3.500436918102423e-008 0.9999999403953552 0 2.75101122437782e-014 -1 2.288952989822068e-013 0 0.04958733543753624 0.1757381856441498 0.08959835022687912 1 + + +0.9999898672103882 1.657488901685156e-008 -0.004498782102018595 0 -0.004498789552599192 -1.781053349247941e-008 -0.9999898076057434 0 -1.665473980949628e-008 1 1.726835030524399e-008 0 -0.02312494441866875 0.2477381676435471 0.2203545719385147 1 + + +1 -6.184104131534696e-005 -1.004268028736988e-006 0 1.011203266898519e-006 1.773524793691195e-008 0.9999999403953552 0 -6.184104131534696e-005 -1 -1.720678532990405e-008 0 0.05108793079853058 0.325738400220871 0.091098353266716 1 + + +0.9999933242797852 1.67195413069976e-008 0.003653878346085548 0 0.003653871593996882 -1.767486601522705e-008 -0.9999932646751404 0 -1.665473980949628e-008 1 1.726829879089564e-008 0 0.08119497448205948 0.2477381974458695 0.2201460748910904 1 + + +-1.552728390308289e-009 5.031413063960599e-009 -1 0 5.031413063960599e-009 1 5.031413063960599e-009 0 1 -5.031413063960599e-009 -1.552728390308289e-009 0 0.2239999920129776 0.03198792785406113 0.02350873313844204 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999868869782 0.02160527743399143 -0.1053286716341972 1 + + +-5.582201367815287e-013 -0.0009254564647562802 -0.9999995827674866 0 -6.028238463962055e-010 -0.9999995827674866 0.0009254564647562802 0 -1 6.028241239519616e-010 3.326781192647572e-016 0 -0.2949999868869782 0.02149887755513191 0.0004925570683553815 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999868869782 0.1238077878952026 -0.100101500749588 1 + + +2.757793993168889e-013 4.575816179956671e-013 1 0 4.575816179956671e-013 -1 4.575816179956671e-013 0 1 4.575816179956671e-013 -2.757793993168889e-013 0 0.1000000014901161 -0.1338488310575485 0.03437212482094765 1 + + +4.052314039881821e-013 1.110223024625157e-015 1 0 1.110223024625157e-015 1 -1.110223024625157e-015 0 -1 1.110223024625157e-015 4.052314039881821e-013 0 -0.1000000014901161 -0.06615117192268372 0.01437209825962782 1 + + +4.052314039881821e-013 1.110223024625157e-015 1 0 1.110223024625157e-015 1 -1.110223024625157e-015 0 -1 1.110223024625157e-015 4.052314039881821e-013 0 -0.1000000014901161 -0.06615117937326431 -0.005627896636724472 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine3.plmxml b/data/tests/Jt/Engine/2_Cylinder_Engine3.plmxml new file mode 100644 index 000000000..baaba2887 --- /dev/null +++ b/data/tests/Jt/Engine/2_Cylinder_Engine3.plmxml @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999868869782 0.1321395188570023 -0.003983345814049244 1 + + +2.757793993168889e-013 4.575816179956671e-013 1 0 4.575816179956671e-013 -1 4.575816179956671e-013 0 1 4.575816179956671e-013 -2.757793993168889e-013 0 0.1000000014901161 -0.1338488310575485 0.05437212437391281 1 + + +0.9861037135124207 -0.1661308258771896 -1.166810754732375e-015 0 0.1661308258771896 0.9861037135124207 -1.062013085640994e-015 0 1.327029577804367e-015 8.534118465009541e-016 1 0 0.07101806253194809 0.02219301462173462 0.02199999988079071 1 + + +-1 1.10096191110321e-032 -7.293991291219912e-017 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.1368601024150848 0.06445372104644775 0.003820367390289903 1 + + +-1 -1.334063881586189e-008 7.982825511732017e-010 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.294677197933197 0.07397986948490143 0.01617963239550591 1 + + +0.9995650053024292 0.02949320152401924 -7.979323313200837e-010 0 -0.0294931884855032 0.9995650053024292 2.354164085893729e-011 0 -3.085015966644567e-015 2.168479519145078e-015 1 0 -0.0453154630959034 -0.02461725845932961 -0.02632036805152893 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0.1368601024150848 -0.06445372104644775 -0.03617963194847107 1 + + +-1 -1.334063881586189e-008 7.041613514502387e-009 0 -1.003604666278664e-019 -1 1.355268465125744e-016 0 -1.736007260287489e-016 1.355268465125744e-016 1 0 -0.294677197933197 0.07397986948490143 0.0161796361207962 1 + + +0.9995650053024292 0.02949320152401924 -7.038550631222051e-009 0 -0.0294931884855032 0.9995650053024292 2.076799010541919e-010 0 1.57434811062825e-016 -2.681045890006053e-016 1 0 -0.0453154630959034 -0.02461725845932961 -0.02632036432623863 1 + + +0.7071067690849304 -0.7071067690849304 4.055928498874345e-013 0 0.7071067690849304 0.7071067690849304 6.101357784178425e-016 0 -2.872288724139332e-013 2.863660101149607e-013 1 0 0.04717867448925972 -0.0528213270008564 -0.08894477039575577 1 + + +1.214013511940948e-008 -7.440697502580917e-010 1 0 -0.9059386253356934 0.4234090149402618 3.675416633368289e-013 0 -0.4234090149402618 -0.9059386253356934 1.728632428171784e-013 0 -0.03029589354991913 -0.05256131291389465 0.02505522221326828 1 + + +-0.4234090149402618 -0.9059386253356934 1.726649286873036e-013 0 -0.9059386253356934 0.4234090149402618 3.675724817835818e-013 0 -1.214013511940948e-008 7.440699723026967e-010 -1 0 -0.09059386700391769 -0.02437981590628624 -0.04005522653460503 1 + + +-0.5 -0.8660253882408142 -2.979083167524747e-016 0 0.8660253882408142 -0.5 -7.816530680941419e-016 0 5.279772353637604e-016 -6.488226847947026e-016 1 0 0.01809818297624588 -0.06969784200191498 -0.1055598109960556 1 + + +-0.9390942454338074 0.3436597287654877 1.284025318025572e-016 0 -0.3436597883701325 -0.9390941858291626 -6.660528172495127e-016 0 2.47777798279003e-008 -2.063888393522007e-009 1 0 -0.05131101608276367 -0.05052240565419197 0.1075598075985909 1 + + +-0.9390942454338074 0.3436597287654877 3.809448359261655e-016 0 -0.3436597883701325 -0.9390941858291626 -2.583991531420675e-015 0 2.47777798279003e-008 -2.063890391923451e-009 1 0 -0.05131101980805397 -0.05052240565419197 -0.01844018884003162 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1 -5.031413063960599e-009 -1.553538520049358e-009 0 1.553538409027055e-009 -1.993428355717697e-008 1 0 -5.031413063960599e-009 -1 -1.993428355717697e-008 0 0.1269356608390808 -5.273894387869405e-008 -0.0365588441491127 1 + + +-1 -1.490642098644912e-008 -1.665472915135524e-008 0 1.665472915135524e-008 -1.764261092773722e-008 -1 0 1.490642098644912e-008 -1 1.764261092773722e-008 0 -0.1269356608390808 3.299700068737366e-009 0.0365588404238224 1 + + +2.459232373297482e-009 0.7071067690849304 -0.7071067690849304 0 -4.656259378066352e-009 -0.7071067690849304 -0.7071067690849304 0 -1 5.031412619871389e-009 1.55353274688963e-009 0 0.06499999761581421 0.1287170201539993 -0.003270523622632027 1 + + +-1.553133399667672e-009 5.031413063960599e-009 -1 0 5.031413063960599e-009 1 5.031413063960599e-009 0 1 -5.031413063960599e-009 -1.553133399667672e-009 0 0.2239999920129776 0.03048792481422424 0.02500873245298863 1 + + +1.665474158585312e-008 1.004267005555448e-006 -1 0 -1 -1.666503557373744e-008 -1.665475757306467e-008 0 -1.6665051560949e-008 1 1.004267005555448e-006 0 -0.04826182126998901 -0.05911042168736458 0.03459598124027252 1 + + +1 9.947598300641403e-014 -1.004267005555448e-006 0 1.011203266898519e-006 3.500436918102423e-008 0.9999999403953552 0 2.75101122437782e-014 -1 2.288952989822068e-013 0 0.04958733543753624 0.1757381856441498 0.08959835022687912 1 + + +1 9.977915303889529e-014 -9.877358024823479e-007 0 -9.946720638254192e-007 -3.500436562831055e-008 -0.9999999403953552 0 -2.75101122437782e-014 1 -2.288952989822068e-013 0 0.02452629990875721 0.2137382179498673 0.2830735743045807 1 + + +0.9999898672103882 1.657488901685156e-008 -0.004498782102018595 0 -0.004498789552599192 -1.781053349247941e-008 -0.9999898076057434 0 -1.665473980949628e-008 1 1.726835030524399e-008 0 -0.02312494441866875 0.2477381676435471 0.2203545719385147 1 + + +0.9999974370002747 -7.939097296238984e-011 -0.002271066652610898 0 9.118318147522016e-016 1 3.807415215490448e-015 0 0.002271073637530208 3.500404588407946e-008 0.9999973773956299 0 -0.0001340909366263077 -0.01299998629838228 0.0001236627285834402 1 + + +-0.9999850392341614 -0.004973083734512329 -0.002270016819238663 0 0.004973071627318859 -0.9999875426292419 1.127185623772675e-005 0 -0.002270089229568839 -4.575558421038295e-008 0.9999972581863403 0 0.0487947128713131 0.7686771750450134 -0.02040251158177853 1 + + +1 -7.424300063618716e-011 1.35305974757749e-010 0 1.276140897124513e-015 0.9999998807907105 4.341043060584901e-016 0 -4.433523059788058e-008 -2.848764957263938e-008 0.9999998211860657 0 -1.748614808505522e-009 -9.381160293031599e-010 -7.228971310446752e-010 1 + + +0.9999973773956299 1.651584646822357e-008 0.002270044526085258 0 -1.669391558323241e-008 0.9999998807907105 1.723048725921217e-008 0 -0.002270088996738195 -4.57557440824985e-008 0.9999972581863403 0 0.04950515553355217 0.3443533480167389 0.07959935814142227 1 + + +0.9999973773956299 1.651585179729409e-008 0.002270044526085258 0 1.669392091230293e-008 -0.9999998807907105 -1.723048725921217e-008 0 0.002270088996738195 4.57557440824985e-008 -0.9999972581863403 0 0.04947110638022423 0.2571229636669159 0.09459931403398514 1 + + +0.9984452724456787 1.914222380605679e-008 -0.05574143305420876 0 -0.05574139580130577 4.472066095217997e-008 -0.9984451532363892 0 -1.669391203051873e-008 1 1.723049436463953e-008 0 0.01820174790918827 0.326738178730011 0.2976770401000977 1 + + +0.9984543323516846 1.913488922866691e-008 -0.05557771772146225 0 -0.05557768046855927 4.472379444564467e-008 -0.998454213142395 0 -1.669391025416189e-008 0.9999998807907105 1.723049436463953e-008 0 0.06816709786653519 0.326738178730011 0.2977887094020844 1 + + +1 -7.424300063618716e-011 1.35305974757749e-010 0 1.276140897124513e-015 0.9999998807907105 4.341043060584901e-016 0 -4.433523059788058e-008 -2.848764957263938e-008 0.9999998211860657 0 -4.064914627122107e-009 -1.459414988858043e-008 -0.09999953210353851 1 + + +0.9999974370002747 1.662746029751361e-008 0.002270044526085258 0 -1.669391735958925e-008 1.00000011920929 1.723049081192585e-008 0 -0.002270061522722244 -2.438619972622291e-008 0.9999974966049194 0 0.04973216727375984 0.3443534076213837 0.07959914952516556 1 + + +0.9999974370002747 1.662746562658413e-008 0.002270044526085258 0 1.669392268865977e-008 -1.00000011920929 -1.723049081192585e-008 0 0.002270061522722244 2.438619972622291e-008 -0.9999974966049194 0 0.0496981143951416 0.2571230232715607 0.09459911286830902 1 + + +0.9986630082130432 1.791910797521723e-008 -0.05169311910867691 0 -0.05169309675693512 2.345346850063379e-008 -0.998663067817688 0 -1.669391025416189e-008 1.00000011920929 1.72305067991374e-008 0 0.01757495850324631 0.3267382085323334 0.2976291477680206 1 + + +0.9986716508865356 1.791518755567267e-008 -0.05152621492743492 0 -0.05152619630098343 2.345645455648082e-008 -0.9986717104911804 0 -1.669391025416189e-008 1.00000011920929 1.723049791735321e-008 0 0.06753963232040405 0.3267382085323334 0.2977406084537506 1 + + +-0.9999873042106628 -0.004487393889576197 -0.00227002170868218 0 0.004487383179366589 -0.9999898076057434 1.016931855701841e-005 0 -0.002270088996738195 -4.575493051106605e-008 0.9999972581863403 0 -0.02998023852705956 0.7686992287635803 -0.02058133110404015 1 + + +-0.821344792842865 -0.3829995691776276 0.4227339625358582 0 -0.3831273019313812 -0.1786547750234604 -0.9062537550926209 0 0.4226182997226715 -0.9063078165054321 -4.468796817036491e-007 0 -0.2707940638065338 0.1454340070486069 0.1220441088080406 1 + + +0.4546822905540466 0.654166042804718 0.6044259667396545 0 -0.8696395754814148 0.4726209938526154 0.1426760256290436 0 -0.1923305839300156 -0.5905050039291382 0.7837809920310974 0 0.09187051653862 0.08063256740570068 0.1662608832120895 1 + + +0.7850326299667358 0.06081443279981613 -0.6164620518684387 0 -0.1356190741062164 0.9878997206687927 -0.07524674385786057 0 0.6044265031814575 0.1426751911640167 0.7837809920310974 0 -0.001248535001650453 -0.2500619888305664 -0.09022713452577591 1 + + +0.7850326299667358 0.06081448495388031 -0.6164620518684387 0 -0.3924773633480072 -0.7211050391197205 -0.5709372162818909 0 -0.4792551398277283 0.6901518106460571 -0.5422225594520569 0 0.0455969013273716 0.2435131669044495 0.06938881427049637 1 + + +1 -3.002940829333056e-008 3.437022044749938e-008 0 -4.150651022882812e-008 1.000000238418579 4.017514854126603e-008 0 3.73510147255729e-008 2.773385787691041e-008 1 0 -1.489124112907803e-008 -4.276215381793236e-009 1.08718030134014e-008 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1410751193761826 0.09142301231622696 -0.3314632773399353 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.05227819457650185 0.07644443958997726 -0.1796288043260574 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1347948610782623 0.09093648940324783 -0.3265315294265747 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.05855846777558327 0.07595790922641754 -0.1746970862150192 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1285146176815033 0.0904499888420105 -0.3215998709201813 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.0648387148976326 0.07547140121459961 -0.1697653979063034 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1222343519330025 0.08996346592903137 -0.3166681826114655 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.07111898809671402 0.07498487830162048 -0.1648336797952652 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1159540787339211 0.08947695046663284 -0.3117364346981049 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.07739924639463425 0.07449836283922195 -0.1599020063877106 1 + + +-0.4546823501586914 0.6541661024093628 -0.6044260263442993 0 0.8696396350860596 0.4726210236549377 -0.1426760405302048 0 0.192330613732338 -0.5905051231384277 -0.7837811708450317 0 0.01489819493144751 0.08582951128482819 -0.04803464561700821 1 + + +1 2.298901691233368e-008 -2.432995493961698e-008 0 -3.89851670945518e-008 0.9999998807907105 -1.280528216796029e-008 0 -3.000558379540053e-008 -2.485903749516183e-008 0.9999998807907105 0 -1.494453005790319e-009 -7.655864275868396e-010 -5.496130661697407e-009 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1413719058036804 0.08810769766569138 -0.3271084725856781 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.05524870008230209 0.07287602126598358 -0.1727083474397659 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1366616934537888 0.08774281293153763 -0.3234097063541412 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.05995889753103256 0.07251112163066864 -0.1690095812082291 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1319515109062195 0.08737793564796448 -0.3197109401226044 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.06466909497976303 0.07214623689651489 -0.165310800075531 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.127241313457489 0.08701304346323013 -0.3160121440887451 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.0693792924284935 0.07178134471178055 -0.1616120338439941 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1225311160087585 0.08664815127849579 -0.3123133778572083 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.07408948242664337 0.0714164674282074 -0.1579132527112961 1 + + +0.7850325107574463 0.06081444025039673 -0.6164620518684387 0 -0.135619044303894 0.9878994226455689 -0.07524680346250534 0 0.6044264435768127 0.1426751613616943 0.7837807536125183 0 -0.005746716633439064 -0.250409871339798 -0.08668788522481918 1 + + +0.7850325703620911 0.06081447005271912 -0.6164620518684387 0 -0.3681581914424896 -0.7545340657234192 -0.543265700340271 0 -0.498180091381073 0.6534368991851807 -0.5699445009231567 0 0.03418708592653275 0.2526659965515137 0.06506367027759552 1 + + +0.9026297330856323 0.4304179251194 -9.149687798526429e-007 0 -0.4304179251194 0.9026297330856323 4.554329109396349e-007 0 1.028840756589489e-006 1.773579327846164e-008 0.9999999403953552 0 0.2777610719203949 0.5800805687904358 -0.005389846861362457 1 + + +0.9026297926902771 -0.4304177463054657 -9.298340728491894e-007 0 0.4304177463054657 0.9026297926902771 -4.242589284331189e-007 0 1.028840756589489e-006 1.773579505481848e-008 0.9999999403953552 0 0.3539793193340302 0.3309040069580078 -0.005389927886426449 1 + + +1 -6.184104131534696e-005 -1.004268028736988e-006 0 1.011203266898519e-006 1.773524793691195e-008 0.9999999403953552 0 -6.184104131534696e-005 -1 -1.720678532990405e-008 0 0.05108792707324028 0.3257383704185486 0.09109834581613541 1 + + +0.9999933242797852 1.67195413069976e-008 0.003653878346085548 0 0.003653871593996882 -1.767486601522705e-008 -0.9999932646751404 0 -1.665473980949628e-008 1 1.726829879089564e-008 0 0.08119496703147888 0.2477381825447083 0.2201460599899292 1 + + +-0.8213930130004883 0.3830220103263855 0.4226199984550476 0 -0.3830239772796631 0.1786065548658371 -0.9063069224357605 0 -0.4226182103157044 -0.9063078165054321 4.008188341231289e-007 0 -0.141640841960907 0.3886727094650269 0.1220077648758888 1 + + +-1.552728390308289e-009 5.031413063960599e-009 -1 0 5.031413063960599e-009 1 5.031413063960599e-009 0 1 -5.031413063960599e-009 -1.552728390308289e-009 0 0.2239999771118164 0.03198792412877083 0.02350873127579689 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999570846558 0.02160527557134628 -0.1053286641836166 1 + + +-5.582201367815287e-013 -0.0009254564647562802 -0.9999995827674866 0 -6.028238463962055e-010 -0.9999995827674866 0.0009254564647562802 0 -1 6.028241239519616e-010 3.326781192647572e-016 0 -0.2949999570846558 0.02149887569248676 0.0004925570683553815 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999570846558 0.123807780444622 -0.1001014932990074 1 + + +2.757793993168889e-013 4.575816179956671e-013 1 0 4.575816179956671e-013 -1 4.575816179956671e-013 0 1 4.575816179956671e-013 -2.757793993168889e-013 0 0.09999999403953552 -0.1338488161563873 0.03437212482094765 1 + + +4.052314039881821e-013 1.110223024625157e-015 1 0 1.110223024625157e-015 1 -1.110223024625157e-015 0 -1 1.110223024625157e-015 4.052314039881821e-013 0 -0.09999999403953552 -0.06615116447210312 0.01437209732830524 1 + + +4.052314039881821e-013 1.110223024625157e-015 1 0 1.110223024625157e-015 1 -1.110223024625157e-015 0 -1 1.110223024625157e-015 4.052314039881821e-013 0 -0.09999999403953552 -0.06615117192268372 -0.005627896171063185 1 + + +-0.9861037135124207 0.1661308258771896 1.702963710921711e-016 0 -0.1661308258771896 -0.9861037135124207 -3.509013978502231e-016 0 1.096343463342109e-016 -3.743166442952229e-016 1 0 -0.07101806253194809 -0.02219301089644432 -0.01999999769032002 1 + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + + +-1 -1.334063881586189e-008 -7.982826621955041e-010 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.1368601024150848 0.06445372104644775 0.003820367390289903 1 + + + +-1 -3.025554562441357e-008 -3.172106577409295e-009 0 1.10096191110321e-032 -1.00000011920929 -3.018819071267222e-016 0 -7.293991291219912e-017 -3.018819071267222e-016 1.00000011920929 0 -0.2946771681308746 0.07397986948490143 0.01617963425815105 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + +1 -5.030475147549396e-009 -8.559119635265233e-008 0 1.553537853915543e-009 -1.993428355717697e-008 1 0 -5.03141173169297e-009 -1 -1.993428355717697e-008 0 0.4018276929855347 0.004671174101531506 -0.01877834275364876 1 + + + + + + + + + + + +-1.553142503496474e-009 5.031413952139019e-009 -1 0 5.031442373848449e-009 1 5.031413063960599e-009 0 1 -7.856474439904559e-007 -1.082494804904854e-007 0 0.5421041250228882 0.03720489889383316 0.04404613375663757 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +-1.552729944620523e-009 5.031413063960599e-009 -1 0 5.0314401534024e-009 1 5.031413063960599e-009 0 1 -3.418919334308157e-007 -1.096145751944277e-007 0 0.6029092669487 0.04294551536440849 0.04271972924470902 1 + + + + + \ No newline at end of file diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine3.xml b/data/tests/Jt/Engine/2_Cylinder_Engine3.xml new file mode 100644 index 000000000..baaba2887 --- /dev/null +++ b/data/tests/Jt/Engine/2_Cylinder_Engine3.xml @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999868869782 0.1321395188570023 -0.003983345814049244 1 + + +2.757793993168889e-013 4.575816179956671e-013 1 0 4.575816179956671e-013 -1 4.575816179956671e-013 0 1 4.575816179956671e-013 -2.757793993168889e-013 0 0.1000000014901161 -0.1338488310575485 0.05437212437391281 1 + + +0.9861037135124207 -0.1661308258771896 -1.166810754732375e-015 0 0.1661308258771896 0.9861037135124207 -1.062013085640994e-015 0 1.327029577804367e-015 8.534118465009541e-016 1 0 0.07101806253194809 0.02219301462173462 0.02199999988079071 1 + + +-1 1.10096191110321e-032 -7.293991291219912e-017 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.1368601024150848 0.06445372104644775 0.003820367390289903 1 + + +-1 -1.334063881586189e-008 7.982825511732017e-010 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.294677197933197 0.07397986948490143 0.01617963239550591 1 + + +0.9995650053024292 0.02949320152401924 -7.979323313200837e-010 0 -0.0294931884855032 0.9995650053024292 2.354164085893729e-011 0 -3.085015966644567e-015 2.168479519145078e-015 1 0 -0.0453154630959034 -0.02461725845932961 -0.02632036805152893 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0.1368601024150848 -0.06445372104644775 -0.03617963194847107 1 + + +-1 -1.334063881586189e-008 7.041613514502387e-009 0 -1.003604666278664e-019 -1 1.355268465125744e-016 0 -1.736007260287489e-016 1.355268465125744e-016 1 0 -0.294677197933197 0.07397986948490143 0.0161796361207962 1 + + +0.9995650053024292 0.02949320152401924 -7.038550631222051e-009 0 -0.0294931884855032 0.9995650053024292 2.076799010541919e-010 0 1.57434811062825e-016 -2.681045890006053e-016 1 0 -0.0453154630959034 -0.02461725845932961 -0.02632036432623863 1 + + +0.7071067690849304 -0.7071067690849304 4.055928498874345e-013 0 0.7071067690849304 0.7071067690849304 6.101357784178425e-016 0 -2.872288724139332e-013 2.863660101149607e-013 1 0 0.04717867448925972 -0.0528213270008564 -0.08894477039575577 1 + + +1.214013511940948e-008 -7.440697502580917e-010 1 0 -0.9059386253356934 0.4234090149402618 3.675416633368289e-013 0 -0.4234090149402618 -0.9059386253356934 1.728632428171784e-013 0 -0.03029589354991913 -0.05256131291389465 0.02505522221326828 1 + + +-0.4234090149402618 -0.9059386253356934 1.726649286873036e-013 0 -0.9059386253356934 0.4234090149402618 3.675724817835818e-013 0 -1.214013511940948e-008 7.440699723026967e-010 -1 0 -0.09059386700391769 -0.02437981590628624 -0.04005522653460503 1 + + +-0.5 -0.8660253882408142 -2.979083167524747e-016 0 0.8660253882408142 -0.5 -7.816530680941419e-016 0 5.279772353637604e-016 -6.488226847947026e-016 1 0 0.01809818297624588 -0.06969784200191498 -0.1055598109960556 1 + + +-0.9390942454338074 0.3436597287654877 1.284025318025572e-016 0 -0.3436597883701325 -0.9390941858291626 -6.660528172495127e-016 0 2.47777798279003e-008 -2.063888393522007e-009 1 0 -0.05131101608276367 -0.05052240565419197 0.1075598075985909 1 + + +-0.9390942454338074 0.3436597287654877 3.809448359261655e-016 0 -0.3436597883701325 -0.9390941858291626 -2.583991531420675e-015 0 2.47777798279003e-008 -2.063890391923451e-009 1 0 -0.05131101980805397 -0.05052240565419197 -0.01844018884003162 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1 -5.031413063960599e-009 -1.553538520049358e-009 0 1.553538409027055e-009 -1.993428355717697e-008 1 0 -5.031413063960599e-009 -1 -1.993428355717697e-008 0 0.1269356608390808 -5.273894387869405e-008 -0.0365588441491127 1 + + +-1 -1.490642098644912e-008 -1.665472915135524e-008 0 1.665472915135524e-008 -1.764261092773722e-008 -1 0 1.490642098644912e-008 -1 1.764261092773722e-008 0 -0.1269356608390808 3.299700068737366e-009 0.0365588404238224 1 + + +2.459232373297482e-009 0.7071067690849304 -0.7071067690849304 0 -4.656259378066352e-009 -0.7071067690849304 -0.7071067690849304 0 -1 5.031412619871389e-009 1.55353274688963e-009 0 0.06499999761581421 0.1287170201539993 -0.003270523622632027 1 + + +-1.553133399667672e-009 5.031413063960599e-009 -1 0 5.031413063960599e-009 1 5.031413063960599e-009 0 1 -5.031413063960599e-009 -1.553133399667672e-009 0 0.2239999920129776 0.03048792481422424 0.02500873245298863 1 + + +1.665474158585312e-008 1.004267005555448e-006 -1 0 -1 -1.666503557373744e-008 -1.665475757306467e-008 0 -1.6665051560949e-008 1 1.004267005555448e-006 0 -0.04826182126998901 -0.05911042168736458 0.03459598124027252 1 + + +1 9.947598300641403e-014 -1.004267005555448e-006 0 1.011203266898519e-006 3.500436918102423e-008 0.9999999403953552 0 2.75101122437782e-014 -1 2.288952989822068e-013 0 0.04958733543753624 0.1757381856441498 0.08959835022687912 1 + + +1 9.977915303889529e-014 -9.877358024823479e-007 0 -9.946720638254192e-007 -3.500436562831055e-008 -0.9999999403953552 0 -2.75101122437782e-014 1 -2.288952989822068e-013 0 0.02452629990875721 0.2137382179498673 0.2830735743045807 1 + + +0.9999898672103882 1.657488901685156e-008 -0.004498782102018595 0 -0.004498789552599192 -1.781053349247941e-008 -0.9999898076057434 0 -1.665473980949628e-008 1 1.726835030524399e-008 0 -0.02312494441866875 0.2477381676435471 0.2203545719385147 1 + + +0.9999974370002747 -7.939097296238984e-011 -0.002271066652610898 0 9.118318147522016e-016 1 3.807415215490448e-015 0 0.002271073637530208 3.500404588407946e-008 0.9999973773956299 0 -0.0001340909366263077 -0.01299998629838228 0.0001236627285834402 1 + + +-0.9999850392341614 -0.004973083734512329 -0.002270016819238663 0 0.004973071627318859 -0.9999875426292419 1.127185623772675e-005 0 -0.002270089229568839 -4.575558421038295e-008 0.9999972581863403 0 0.0487947128713131 0.7686771750450134 -0.02040251158177853 1 + + +1 -7.424300063618716e-011 1.35305974757749e-010 0 1.276140897124513e-015 0.9999998807907105 4.341043060584901e-016 0 -4.433523059788058e-008 -2.848764957263938e-008 0.9999998211860657 0 -1.748614808505522e-009 -9.381160293031599e-010 -7.228971310446752e-010 1 + + +0.9999973773956299 1.651584646822357e-008 0.002270044526085258 0 -1.669391558323241e-008 0.9999998807907105 1.723048725921217e-008 0 -0.002270088996738195 -4.57557440824985e-008 0.9999972581863403 0 0.04950515553355217 0.3443533480167389 0.07959935814142227 1 + + +0.9999973773956299 1.651585179729409e-008 0.002270044526085258 0 1.669392091230293e-008 -0.9999998807907105 -1.723048725921217e-008 0 0.002270088996738195 4.57557440824985e-008 -0.9999972581863403 0 0.04947110638022423 0.2571229636669159 0.09459931403398514 1 + + +0.9984452724456787 1.914222380605679e-008 -0.05574143305420876 0 -0.05574139580130577 4.472066095217997e-008 -0.9984451532363892 0 -1.669391203051873e-008 1 1.723049436463953e-008 0 0.01820174790918827 0.326738178730011 0.2976770401000977 1 + + +0.9984543323516846 1.913488922866691e-008 -0.05557771772146225 0 -0.05557768046855927 4.472379444564467e-008 -0.998454213142395 0 -1.669391025416189e-008 0.9999998807907105 1.723049436463953e-008 0 0.06816709786653519 0.326738178730011 0.2977887094020844 1 + + +1 -7.424300063618716e-011 1.35305974757749e-010 0 1.276140897124513e-015 0.9999998807907105 4.341043060584901e-016 0 -4.433523059788058e-008 -2.848764957263938e-008 0.9999998211860657 0 -4.064914627122107e-009 -1.459414988858043e-008 -0.09999953210353851 1 + + +0.9999974370002747 1.662746029751361e-008 0.002270044526085258 0 -1.669391735958925e-008 1.00000011920929 1.723049081192585e-008 0 -0.002270061522722244 -2.438619972622291e-008 0.9999974966049194 0 0.04973216727375984 0.3443534076213837 0.07959914952516556 1 + + +0.9999974370002747 1.662746562658413e-008 0.002270044526085258 0 1.669392268865977e-008 -1.00000011920929 -1.723049081192585e-008 0 0.002270061522722244 2.438619972622291e-008 -0.9999974966049194 0 0.0496981143951416 0.2571230232715607 0.09459911286830902 1 + + +0.9986630082130432 1.791910797521723e-008 -0.05169311910867691 0 -0.05169309675693512 2.345346850063379e-008 -0.998663067817688 0 -1.669391025416189e-008 1.00000011920929 1.72305067991374e-008 0 0.01757495850324631 0.3267382085323334 0.2976291477680206 1 + + +0.9986716508865356 1.791518755567267e-008 -0.05152621492743492 0 -0.05152619630098343 2.345645455648082e-008 -0.9986717104911804 0 -1.669391025416189e-008 1.00000011920929 1.723049791735321e-008 0 0.06753963232040405 0.3267382085323334 0.2977406084537506 1 + + +-0.9999873042106628 -0.004487393889576197 -0.00227002170868218 0 0.004487383179366589 -0.9999898076057434 1.016931855701841e-005 0 -0.002270088996738195 -4.575493051106605e-008 0.9999972581863403 0 -0.02998023852705956 0.7686992287635803 -0.02058133110404015 1 + + +-0.821344792842865 -0.3829995691776276 0.4227339625358582 0 -0.3831273019313812 -0.1786547750234604 -0.9062537550926209 0 0.4226182997226715 -0.9063078165054321 -4.468796817036491e-007 0 -0.2707940638065338 0.1454340070486069 0.1220441088080406 1 + + +0.4546822905540466 0.654166042804718 0.6044259667396545 0 -0.8696395754814148 0.4726209938526154 0.1426760256290436 0 -0.1923305839300156 -0.5905050039291382 0.7837809920310974 0 0.09187051653862 0.08063256740570068 0.1662608832120895 1 + + +0.7850326299667358 0.06081443279981613 -0.6164620518684387 0 -0.1356190741062164 0.9878997206687927 -0.07524674385786057 0 0.6044265031814575 0.1426751911640167 0.7837809920310974 0 -0.001248535001650453 -0.2500619888305664 -0.09022713452577591 1 + + +0.7850326299667358 0.06081448495388031 -0.6164620518684387 0 -0.3924773633480072 -0.7211050391197205 -0.5709372162818909 0 -0.4792551398277283 0.6901518106460571 -0.5422225594520569 0 0.0455969013273716 0.2435131669044495 0.06938881427049637 1 + + +1 -3.002940829333056e-008 3.437022044749938e-008 0 -4.150651022882812e-008 1.000000238418579 4.017514854126603e-008 0 3.73510147255729e-008 2.773385787691041e-008 1 0 -1.489124112907803e-008 -4.276215381793236e-009 1.08718030134014e-008 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1410751193761826 0.09142301231622696 -0.3314632773399353 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.05227819457650185 0.07644443958997726 -0.1796288043260574 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1347948610782623 0.09093648940324783 -0.3265315294265747 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.05855846777558327 0.07595790922641754 -0.1746970862150192 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1285146176815033 0.0904499888420105 -0.3215998709201813 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.0648387148976326 0.07547140121459961 -0.1697653979063034 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1222343519330025 0.08996346592903137 -0.3166681826114655 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.07111898809671402 0.07498487830162048 -0.1648336797952652 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1159540787339211 0.08947695046663284 -0.3117364346981049 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.07739924639463425 0.07449836283922195 -0.1599020063877106 1 + + +-0.4546823501586914 0.6541661024093628 -0.6044260263442993 0 0.8696396350860596 0.4726210236549377 -0.1426760405302048 0 0.192330613732338 -0.5905051231384277 -0.7837811708450317 0 0.01489819493144751 0.08582951128482819 -0.04803464561700821 1 + + +1 2.298901691233368e-008 -2.432995493961698e-008 0 -3.89851670945518e-008 0.9999998807907105 -1.280528216796029e-008 0 -3.000558379540053e-008 -2.485903749516183e-008 0.9999998807907105 0 -1.494453005790319e-009 -7.655864275868396e-010 -5.496130661697407e-009 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1413719058036804 0.08810769766569138 -0.3271084725856781 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.05524870008230209 0.07287602126598358 -0.1727083474397659 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1366616934537888 0.08774281293153763 -0.3234097063541412 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.05995889753103256 0.07251112163066864 -0.1690095812082291 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1319515109062195 0.08737793564796448 -0.3197109401226044 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.06466909497976303 0.07214623689651489 -0.165310800075531 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.127241313457489 0.08701304346323013 -0.3160121440887451 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.0693792924284935 0.07178134471178055 -0.1616120338439941 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1225311160087585 0.08664815127849579 -0.3123133778572083 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.07408948242664337 0.0714164674282074 -0.1579132527112961 1 + + +0.7850325107574463 0.06081444025039673 -0.6164620518684387 0 -0.135619044303894 0.9878994226455689 -0.07524680346250534 0 0.6044264435768127 0.1426751613616943 0.7837807536125183 0 -0.005746716633439064 -0.250409871339798 -0.08668788522481918 1 + + +0.7850325703620911 0.06081447005271912 -0.6164620518684387 0 -0.3681581914424896 -0.7545340657234192 -0.543265700340271 0 -0.498180091381073 0.6534368991851807 -0.5699445009231567 0 0.03418708592653275 0.2526659965515137 0.06506367027759552 1 + + +0.9026297330856323 0.4304179251194 -9.149687798526429e-007 0 -0.4304179251194 0.9026297330856323 4.554329109396349e-007 0 1.028840756589489e-006 1.773579327846164e-008 0.9999999403953552 0 0.2777610719203949 0.5800805687904358 -0.005389846861362457 1 + + +0.9026297926902771 -0.4304177463054657 -9.298340728491894e-007 0 0.4304177463054657 0.9026297926902771 -4.242589284331189e-007 0 1.028840756589489e-006 1.773579505481848e-008 0.9999999403953552 0 0.3539793193340302 0.3309040069580078 -0.005389927886426449 1 + + +1 -6.184104131534696e-005 -1.004268028736988e-006 0 1.011203266898519e-006 1.773524793691195e-008 0.9999999403953552 0 -6.184104131534696e-005 -1 -1.720678532990405e-008 0 0.05108792707324028 0.3257383704185486 0.09109834581613541 1 + + +0.9999933242797852 1.67195413069976e-008 0.003653878346085548 0 0.003653871593996882 -1.767486601522705e-008 -0.9999932646751404 0 -1.665473980949628e-008 1 1.726829879089564e-008 0 0.08119496703147888 0.2477381825447083 0.2201460599899292 1 + + +-0.8213930130004883 0.3830220103263855 0.4226199984550476 0 -0.3830239772796631 0.1786065548658371 -0.9063069224357605 0 -0.4226182103157044 -0.9063078165054321 4.008188341231289e-007 0 -0.141640841960907 0.3886727094650269 0.1220077648758888 1 + + +-1.552728390308289e-009 5.031413063960599e-009 -1 0 5.031413063960599e-009 1 5.031413063960599e-009 0 1 -5.031413063960599e-009 -1.552728390308289e-009 0 0.2239999771118164 0.03198792412877083 0.02350873127579689 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999570846558 0.02160527557134628 -0.1053286641836166 1 + + +-5.582201367815287e-013 -0.0009254564647562802 -0.9999995827674866 0 -6.028238463962055e-010 -0.9999995827674866 0.0009254564647562802 0 -1 6.028241239519616e-010 3.326781192647572e-016 0 -0.2949999570846558 0.02149887569248676 0.0004925570683553815 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999570846558 0.123807780444622 -0.1001014932990074 1 + + +2.757793993168889e-013 4.575816179956671e-013 1 0 4.575816179956671e-013 -1 4.575816179956671e-013 0 1 4.575816179956671e-013 -2.757793993168889e-013 0 0.09999999403953552 -0.1338488161563873 0.03437212482094765 1 + + +4.052314039881821e-013 1.110223024625157e-015 1 0 1.110223024625157e-015 1 -1.110223024625157e-015 0 -1 1.110223024625157e-015 4.052314039881821e-013 0 -0.09999999403953552 -0.06615116447210312 0.01437209732830524 1 + + +4.052314039881821e-013 1.110223024625157e-015 1 0 1.110223024625157e-015 1 -1.110223024625157e-015 0 -1 1.110223024625157e-015 4.052314039881821e-013 0 -0.09999999403953552 -0.06615117192268372 -0.005627896171063185 1 + + +-0.9861037135124207 0.1661308258771896 1.702963710921711e-016 0 -0.1661308258771896 -0.9861037135124207 -3.509013978502231e-016 0 1.096343463342109e-016 -3.743166442952229e-016 1 0 -0.07101806253194809 -0.02219301089644432 -0.01999999769032002 1 + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + + +-1 -1.334063881586189e-008 -7.982826621955041e-010 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.1368601024150848 0.06445372104644775 0.003820367390289903 1 + + + +-1 -3.025554562441357e-008 -3.172106577409295e-009 0 1.10096191110321e-032 -1.00000011920929 -3.018819071267222e-016 0 -7.293991291219912e-017 -3.018819071267222e-016 1.00000011920929 0 -0.2946771681308746 0.07397986948490143 0.01617963425815105 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + +1 -5.030475147549396e-009 -8.559119635265233e-008 0 1.553537853915543e-009 -1.993428355717697e-008 1 0 -5.03141173169297e-009 -1 -1.993428355717697e-008 0 0.4018276929855347 0.004671174101531506 -0.01877834275364876 1 + + + + + + + + + + + +-1.553142503496474e-009 5.031413952139019e-009 -1 0 5.031442373848449e-009 1 5.031413063960599e-009 0 1 -7.856474439904559e-007 -1.082494804904854e-007 0 0.5421041250228882 0.03720489889383316 0.04404613375663757 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +-1.552729944620523e-009 5.031413063960599e-009 -1 0 5.0314401534024e-009 1 5.031413063960599e-009 0 1 -3.418919334308157e-007 -1.096145751944277e-007 0 0.6029092669487 0.04294551536440849 0.04271972924470902 1 + + + + + \ No newline at end of file diff --git a/data/tests/Jt/Engine/2_Cylinder_Engine3_Exploded.plmxml b/data/tests/Jt/Engine/2_Cylinder_Engine3_Exploded.plmxml new file mode 100644 index 000000000..baaba2887 --- /dev/null +++ b/data/tests/Jt/Engine/2_Cylinder_Engine3_Exploded.plmxml @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999868869782 0.1321395188570023 -0.003983345814049244 1 + + +2.757793993168889e-013 4.575816179956671e-013 1 0 4.575816179956671e-013 -1 4.575816179956671e-013 0 1 4.575816179956671e-013 -2.757793993168889e-013 0 0.1000000014901161 -0.1338488310575485 0.05437212437391281 1 + + +0.9861037135124207 -0.1661308258771896 -1.166810754732375e-015 0 0.1661308258771896 0.9861037135124207 -1.062013085640994e-015 0 1.327029577804367e-015 8.534118465009541e-016 1 0 0.07101806253194809 0.02219301462173462 0.02199999988079071 1 + + +-1 1.10096191110321e-032 -7.293991291219912e-017 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.1368601024150848 0.06445372104644775 0.003820367390289903 1 + + +-1 -1.334063881586189e-008 7.982825511732017e-010 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.294677197933197 0.07397986948490143 0.01617963239550591 1 + + +0.9995650053024292 0.02949320152401924 -7.979323313200837e-010 0 -0.0294931884855032 0.9995650053024292 2.354164085893729e-011 0 -3.085015966644567e-015 2.168479519145078e-015 1 0 -0.0453154630959034 -0.02461725845932961 -0.02632036805152893 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0.1368601024150848 -0.06445372104644775 -0.03617963194847107 1 + + +-1 -1.334063881586189e-008 7.041613514502387e-009 0 -1.003604666278664e-019 -1 1.355268465125744e-016 0 -1.736007260287489e-016 1.355268465125744e-016 1 0 -0.294677197933197 0.07397986948490143 0.0161796361207962 1 + + +0.9995650053024292 0.02949320152401924 -7.038550631222051e-009 0 -0.0294931884855032 0.9995650053024292 2.076799010541919e-010 0 1.57434811062825e-016 -2.681045890006053e-016 1 0 -0.0453154630959034 -0.02461725845932961 -0.02632036432623863 1 + + +0.7071067690849304 -0.7071067690849304 4.055928498874345e-013 0 0.7071067690849304 0.7071067690849304 6.101357784178425e-016 0 -2.872288724139332e-013 2.863660101149607e-013 1 0 0.04717867448925972 -0.0528213270008564 -0.08894477039575577 1 + + +1.214013511940948e-008 -7.440697502580917e-010 1 0 -0.9059386253356934 0.4234090149402618 3.675416633368289e-013 0 -0.4234090149402618 -0.9059386253356934 1.728632428171784e-013 0 -0.03029589354991913 -0.05256131291389465 0.02505522221326828 1 + + +-0.4234090149402618 -0.9059386253356934 1.726649286873036e-013 0 -0.9059386253356934 0.4234090149402618 3.675724817835818e-013 0 -1.214013511940948e-008 7.440699723026967e-010 -1 0 -0.09059386700391769 -0.02437981590628624 -0.04005522653460503 1 + + +-0.5 -0.8660253882408142 -2.979083167524747e-016 0 0.8660253882408142 -0.5 -7.816530680941419e-016 0 5.279772353637604e-016 -6.488226847947026e-016 1 0 0.01809818297624588 -0.06969784200191498 -0.1055598109960556 1 + + +-0.9390942454338074 0.3436597287654877 1.284025318025572e-016 0 -0.3436597883701325 -0.9390941858291626 -6.660528172495127e-016 0 2.47777798279003e-008 -2.063888393522007e-009 1 0 -0.05131101608276367 -0.05052240565419197 0.1075598075985909 1 + + +-0.9390942454338074 0.3436597287654877 3.809448359261655e-016 0 -0.3436597883701325 -0.9390941858291626 -2.583991531420675e-015 0 2.47777798279003e-008 -2.063890391923451e-009 1 0 -0.05131101980805397 -0.05052240565419197 -0.01844018884003162 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + +1 -5.031413063960599e-009 -1.553538520049358e-009 0 1.553538409027055e-009 -1.993428355717697e-008 1 0 -5.031413063960599e-009 -1 -1.993428355717697e-008 0 0.1269356608390808 -5.273894387869405e-008 -0.0365588441491127 1 + + +-1 -1.490642098644912e-008 -1.665472915135524e-008 0 1.665472915135524e-008 -1.764261092773722e-008 -1 0 1.490642098644912e-008 -1 1.764261092773722e-008 0 -0.1269356608390808 3.299700068737366e-009 0.0365588404238224 1 + + +2.459232373297482e-009 0.7071067690849304 -0.7071067690849304 0 -4.656259378066352e-009 -0.7071067690849304 -0.7071067690849304 0 -1 5.031412619871389e-009 1.55353274688963e-009 0 0.06499999761581421 0.1287170201539993 -0.003270523622632027 1 + + +-1.553133399667672e-009 5.031413063960599e-009 -1 0 5.031413063960599e-009 1 5.031413063960599e-009 0 1 -5.031413063960599e-009 -1.553133399667672e-009 0 0.2239999920129776 0.03048792481422424 0.02500873245298863 1 + + +1.665474158585312e-008 1.004267005555448e-006 -1 0 -1 -1.666503557373744e-008 -1.665475757306467e-008 0 -1.6665051560949e-008 1 1.004267005555448e-006 0 -0.04826182126998901 -0.05911042168736458 0.03459598124027252 1 + + +1 9.947598300641403e-014 -1.004267005555448e-006 0 1.011203266898519e-006 3.500436918102423e-008 0.9999999403953552 0 2.75101122437782e-014 -1 2.288952989822068e-013 0 0.04958733543753624 0.1757381856441498 0.08959835022687912 1 + + +1 9.977915303889529e-014 -9.877358024823479e-007 0 -9.946720638254192e-007 -3.500436562831055e-008 -0.9999999403953552 0 -2.75101122437782e-014 1 -2.288952989822068e-013 0 0.02452629990875721 0.2137382179498673 0.2830735743045807 1 + + +0.9999898672103882 1.657488901685156e-008 -0.004498782102018595 0 -0.004498789552599192 -1.781053349247941e-008 -0.9999898076057434 0 -1.665473980949628e-008 1 1.726835030524399e-008 0 -0.02312494441866875 0.2477381676435471 0.2203545719385147 1 + + +0.9999974370002747 -7.939097296238984e-011 -0.002271066652610898 0 9.118318147522016e-016 1 3.807415215490448e-015 0 0.002271073637530208 3.500404588407946e-008 0.9999973773956299 0 -0.0001340909366263077 -0.01299998629838228 0.0001236627285834402 1 + + +-0.9999850392341614 -0.004973083734512329 -0.002270016819238663 0 0.004973071627318859 -0.9999875426292419 1.127185623772675e-005 0 -0.002270089229568839 -4.575558421038295e-008 0.9999972581863403 0 0.0487947128713131 0.7686771750450134 -0.02040251158177853 1 + + +1 -7.424300063618716e-011 1.35305974757749e-010 0 1.276140897124513e-015 0.9999998807907105 4.341043060584901e-016 0 -4.433523059788058e-008 -2.848764957263938e-008 0.9999998211860657 0 -1.748614808505522e-009 -9.381160293031599e-010 -7.228971310446752e-010 1 + + +0.9999973773956299 1.651584646822357e-008 0.002270044526085258 0 -1.669391558323241e-008 0.9999998807907105 1.723048725921217e-008 0 -0.002270088996738195 -4.57557440824985e-008 0.9999972581863403 0 0.04950515553355217 0.3443533480167389 0.07959935814142227 1 + + +0.9999973773956299 1.651585179729409e-008 0.002270044526085258 0 1.669392091230293e-008 -0.9999998807907105 -1.723048725921217e-008 0 0.002270088996738195 4.57557440824985e-008 -0.9999972581863403 0 0.04947110638022423 0.2571229636669159 0.09459931403398514 1 + + +0.9984452724456787 1.914222380605679e-008 -0.05574143305420876 0 -0.05574139580130577 4.472066095217997e-008 -0.9984451532363892 0 -1.669391203051873e-008 1 1.723049436463953e-008 0 0.01820174790918827 0.326738178730011 0.2976770401000977 1 + + +0.9984543323516846 1.913488922866691e-008 -0.05557771772146225 0 -0.05557768046855927 4.472379444564467e-008 -0.998454213142395 0 -1.669391025416189e-008 0.9999998807907105 1.723049436463953e-008 0 0.06816709786653519 0.326738178730011 0.2977887094020844 1 + + +1 -7.424300063618716e-011 1.35305974757749e-010 0 1.276140897124513e-015 0.9999998807907105 4.341043060584901e-016 0 -4.433523059788058e-008 -2.848764957263938e-008 0.9999998211860657 0 -4.064914627122107e-009 -1.459414988858043e-008 -0.09999953210353851 1 + + +0.9999974370002747 1.662746029751361e-008 0.002270044526085258 0 -1.669391735958925e-008 1.00000011920929 1.723049081192585e-008 0 -0.002270061522722244 -2.438619972622291e-008 0.9999974966049194 0 0.04973216727375984 0.3443534076213837 0.07959914952516556 1 + + +0.9999974370002747 1.662746562658413e-008 0.002270044526085258 0 1.669392268865977e-008 -1.00000011920929 -1.723049081192585e-008 0 0.002270061522722244 2.438619972622291e-008 -0.9999974966049194 0 0.0496981143951416 0.2571230232715607 0.09459911286830902 1 + + +0.9986630082130432 1.791910797521723e-008 -0.05169311910867691 0 -0.05169309675693512 2.345346850063379e-008 -0.998663067817688 0 -1.669391025416189e-008 1.00000011920929 1.72305067991374e-008 0 0.01757495850324631 0.3267382085323334 0.2976291477680206 1 + + +0.9986716508865356 1.791518755567267e-008 -0.05152621492743492 0 -0.05152619630098343 2.345645455648082e-008 -0.9986717104911804 0 -1.669391025416189e-008 1.00000011920929 1.723049791735321e-008 0 0.06753963232040405 0.3267382085323334 0.2977406084537506 1 + + +-0.9999873042106628 -0.004487393889576197 -0.00227002170868218 0 0.004487383179366589 -0.9999898076057434 1.016931855701841e-005 0 -0.002270088996738195 -4.575493051106605e-008 0.9999972581863403 0 -0.02998023852705956 0.7686992287635803 -0.02058133110404015 1 + + +-0.821344792842865 -0.3829995691776276 0.4227339625358582 0 -0.3831273019313812 -0.1786547750234604 -0.9062537550926209 0 0.4226182997226715 -0.9063078165054321 -4.468796817036491e-007 0 -0.2707940638065338 0.1454340070486069 0.1220441088080406 1 + + +0.4546822905540466 0.654166042804718 0.6044259667396545 0 -0.8696395754814148 0.4726209938526154 0.1426760256290436 0 -0.1923305839300156 -0.5905050039291382 0.7837809920310974 0 0.09187051653862 0.08063256740570068 0.1662608832120895 1 + + +0.7850326299667358 0.06081443279981613 -0.6164620518684387 0 -0.1356190741062164 0.9878997206687927 -0.07524674385786057 0 0.6044265031814575 0.1426751911640167 0.7837809920310974 0 -0.001248535001650453 -0.2500619888305664 -0.09022713452577591 1 + + +0.7850326299667358 0.06081448495388031 -0.6164620518684387 0 -0.3924773633480072 -0.7211050391197205 -0.5709372162818909 0 -0.4792551398277283 0.6901518106460571 -0.5422225594520569 0 0.0455969013273716 0.2435131669044495 0.06938881427049637 1 + + +1 -3.002940829333056e-008 3.437022044749938e-008 0 -4.150651022882812e-008 1.000000238418579 4.017514854126603e-008 0 3.73510147255729e-008 2.773385787691041e-008 1 0 -1.489124112907803e-008 -4.276215381793236e-009 1.08718030134014e-008 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1410751193761826 0.09142301231622696 -0.3314632773399353 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.05227819457650185 0.07644443958997726 -0.1796288043260574 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1347948610782623 0.09093648940324783 -0.3265315294265747 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.05855846777558327 0.07595790922641754 -0.1746970862150192 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1285146176815033 0.0904499888420105 -0.3215998709201813 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.0648387148976326 0.07547140121459961 -0.1697653979063034 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1222343519330025 0.08996346592903137 -0.3166681826114655 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.07111898809671402 0.07498487830162048 -0.1648336797952652 1 + + +-0.6893028616905212 -0.1355008780956268 0.7116888165473938 0 -0.6755837202072144 0.4749762713909149 -0.5639010667800903 0 -0.2616261541843414 -0.8695042133331299 -0.4189447462558746 0 0.1159540787339211 0.08947695046663284 -0.3117364346981049 1 + + +0.8620703816413879 -0.01532000117003918 -0.506557047367096 0 -0.4340352714061737 0.4936883747577667 -0.7535817623138428 0 0.261626124382019 0.8695042133331299 0.4189446866512299 0 -0.07739924639463425 0.07449836283922195 -0.1599020063877106 1 + + +-0.4546823501586914 0.6541661024093628 -0.6044260263442993 0 0.8696396350860596 0.4726210236549377 -0.1426760405302048 0 0.192330613732338 -0.5905051231384277 -0.7837811708450317 0 0.01489819493144751 0.08582951128482819 -0.04803464561700821 1 + + +1 2.298901691233368e-008 -2.432995493961698e-008 0 -3.89851670945518e-008 0.9999998807907105 -1.280528216796029e-008 0 -3.000558379540053e-008 -2.485903749516183e-008 0.9999998807907105 0 -1.494453005790319e-009 -7.655864275868396e-010 -5.496130661697407e-009 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1413719058036804 0.08810769766569138 -0.3271084725856781 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.05524870008230209 0.07287602126598358 -0.1727083474397659 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1366616934537888 0.08774281293153763 -0.3234097063541412 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.05995889753103256 0.07251112163066864 -0.1690095812082291 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1319515109062195 0.08737793564796448 -0.3197109401226044 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.06466909497976303 0.07214623689651489 -0.165310800075531 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.127241313457489 0.08701304346323013 -0.3160121440887451 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.0693792924284935 0.07178134471178055 -0.1616120338439941 1 + + +-0.7145452499389648 -0.1154179275035858 0.6900026798248291 0 -0.652251660823822 0.4665488302707672 -0.5974109768867493 0 -0.252968043088913 -0.8769325613975525 -0.4086517691612244 0 0.1225311160087585 0.08664815127849579 -0.3123133778572083 1 + + +0.8450331687927246 0.005398655775934458 -0.5346865653991699 0 -0.4710902869701386 0.4805829524993897 -0.7396714687347412 0 0.252968043088913 0.8769325613975525 0.4086517691612244 0 -0.07408948242664337 0.0714164674282074 -0.1579132527112961 1 + + +0.7850325107574463 0.06081444025039673 -0.6164620518684387 0 -0.135619044303894 0.9878994226455689 -0.07524680346250534 0 0.6044264435768127 0.1426751613616943 0.7837807536125183 0 -0.005746716633439064 -0.250409871339798 -0.08668788522481918 1 + + +0.7850325703620911 0.06081447005271912 -0.6164620518684387 0 -0.3681581914424896 -0.7545340657234192 -0.543265700340271 0 -0.498180091381073 0.6534368991851807 -0.5699445009231567 0 0.03418708592653275 0.2526659965515137 0.06506367027759552 1 + + +0.9026297330856323 0.4304179251194 -9.149687798526429e-007 0 -0.4304179251194 0.9026297330856323 4.554329109396349e-007 0 1.028840756589489e-006 1.773579327846164e-008 0.9999999403953552 0 0.2777610719203949 0.5800805687904358 -0.005389846861362457 1 + + +0.9026297926902771 -0.4304177463054657 -9.298340728491894e-007 0 0.4304177463054657 0.9026297926902771 -4.242589284331189e-007 0 1.028840756589489e-006 1.773579505481848e-008 0.9999999403953552 0 0.3539793193340302 0.3309040069580078 -0.005389927886426449 1 + + +1 -6.184104131534696e-005 -1.004268028736988e-006 0 1.011203266898519e-006 1.773524793691195e-008 0.9999999403953552 0 -6.184104131534696e-005 -1 -1.720678532990405e-008 0 0.05108792707324028 0.3257383704185486 0.09109834581613541 1 + + +0.9999933242797852 1.67195413069976e-008 0.003653878346085548 0 0.003653871593996882 -1.767486601522705e-008 -0.9999932646751404 0 -1.665473980949628e-008 1 1.726829879089564e-008 0 0.08119496703147888 0.2477381825447083 0.2201460599899292 1 + + +-0.8213930130004883 0.3830220103263855 0.4226199984550476 0 -0.3830239772796631 0.1786065548658371 -0.9063069224357605 0 -0.4226182103157044 -0.9063078165054321 4.008188341231289e-007 0 -0.141640841960907 0.3886727094650269 0.1220077648758888 1 + + +-1.552728390308289e-009 5.031413063960599e-009 -1 0 5.031413063960599e-009 1 5.031413063960599e-009 0 1 -5.031413063960599e-009 -1.552728390308289e-009 0 0.2239999771118164 0.03198792412877083 0.02350873127579689 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999570846558 0.02160527557134628 -0.1053286641836166 1 + + +-5.582201367815287e-013 -0.0009254564647562802 -0.9999995827674866 0 -6.028238463962055e-010 -0.9999995827674866 0.0009254564647562802 0 -1 6.028241239519616e-010 3.326781192647572e-016 0 -0.2949999570846558 0.02149887569248676 0.0004925570683553815 1 + + +1.421973649939901e-012 0.002356703858822584 -0.9999971985816956 0 -6.033720745257654e-010 -0.9999971985816956 -0.002356703858822584 0 -1 6.033737398603023e-010 -3.700562300775484e-019 0 -0.2949999570846558 0.123807780444622 -0.1001014932990074 1 + + +2.757793993168889e-013 4.575816179956671e-013 1 0 4.575816179956671e-013 -1 4.575816179956671e-013 0 1 4.575816179956671e-013 -2.757793993168889e-013 0 0.09999999403953552 -0.1338488161563873 0.03437212482094765 1 + + +4.052314039881821e-013 1.110223024625157e-015 1 0 1.110223024625157e-015 1 -1.110223024625157e-015 0 -1 1.110223024625157e-015 4.052314039881821e-013 0 -0.09999999403953552 -0.06615116447210312 0.01437209732830524 1 + + +4.052314039881821e-013 1.110223024625157e-015 1 0 1.110223024625157e-015 1 -1.110223024625157e-015 0 -1 1.110223024625157e-015 4.052314039881821e-013 0 -0.09999999403953552 -0.06615117192268372 -0.005627896171063185 1 + + +-0.9861037135124207 0.1661308258771896 1.702963710921711e-016 0 -0.1661308258771896 -0.9861037135124207 -3.509013978502231e-016 0 1.096343463342109e-016 -3.743166442952229e-016 1 0 -0.07101806253194809 -0.02219301089644432 -0.01999999769032002 1 + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + + + + + + + + + +-1 -1.334063881586189e-008 -7.982826621955041e-010 0 1.10096191110321e-032 -1 -3.018818806569426e-016 0 -7.293991291219912e-017 -3.018818806569426e-016 1 0 -0.1368601024150848 0.06445372104644775 0.003820367390289903 1 + + + +-1 -3.025554562441357e-008 -3.172106577409295e-009 0 1.10096191110321e-032 -1.00000011920929 -3.018819071267222e-016 0 -7.293991291219912e-017 -3.018819071267222e-016 1.00000011920929 0 -0.2946771681308746 0.07397986948490143 0.01617963425815105 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 + + + + + + + +1 -5.030475147549396e-009 -8.559119635265233e-008 0 1.553537853915543e-009 -1.993428355717697e-008 1 0 -5.03141173169297e-009 -1 -1.993428355717697e-008 0 0.4018276929855347 0.004671174101531506 -0.01877834275364876 1 + + + + + + + + + + + +-1.553142503496474e-009 5.031413952139019e-009 -1 0 5.031442373848449e-009 1 5.031413063960599e-009 0 1 -7.856474439904559e-007 -1.082494804904854e-007 0 0.5421041250228882 0.03720489889383316 0.04404613375663757 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +-1.552729944620523e-009 5.031413063960599e-009 -1 0 5.0314401534024e-009 1 5.031413063960599e-009 0 1 -3.418919334308157e-007 -1.096145751944277e-007 0 0.6029092669487 0.04294551536440849 0.04271972924470902 1 + + + + + \ No newline at end of file diff --git a/data/tests/PadTest.fcstd b/data/tests/PadTest.fcstd index 8a7223083..628652095 100644 Binary files a/data/tests/PadTest.fcstd and b/data/tests/PadTest.fcstd differ diff --git a/data/tests/PocketTest.fcstd b/data/tests/PocketTest.fcstd index 6acf91ba0..6f8fd2869 100644 Binary files a/data/tests/PocketTest.fcstd and b/data/tests/PocketTest.fcstd differ diff --git a/data/tests/Step/as1-ac-214_small.stp b/data/tests/Step/as1-ac-214_small.stp new file mode 100644 index 000000000..85b358f64 --- /dev/null +++ b/data/tests/Step/as1-ac-214_small.stp @@ -0,0 +1,1519 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('CATIA V5 STEP Exchange'),'2;1'); + +FILE_NAME('C:\\Users\\jriegel\\SW-Entwicklung\\FreeCAD\\temp\\data\\tests\\Step\\as1-ac-214_small.stp','2014-11-09T11:25:11+00:00',('none'),('none'),'CATIA Version 5 Release 19 SP 3 (IN-10)','CATIA V5 STEP AP203','none'); + +FILE_SCHEMA(('CONFIG_CONTROL_DESIGN')); + +ENDSEC; +/* file written by CATIA V5R19 */ +DATA; +#5=PRODUCT('AS1-AC-214','AS1-AC-214','',(#2)) ; +#56=PRODUCT('L-BRACKET','L-BRACKET','',(#2)) ; +#817=PRODUCT('NUT-BOLT ASSEMBLY','NUT-BOLT ASSEMBLY','',(#2)) ; +#825=PRODUCT('BOLT','BOLT','',(#2)) ; +#1058=PRODUCT('NUT','NUT','',(#2)) ; +#1=APPLICATION_CONTEXT('configuration controlled 3D design of mechanical parts and assemblies') ; +#17=PRODUCT_DEFINITION('None',' ',#6,#3) ; +#819=PRODUCT_DEFINITION('None',' ',#818,#3) ; +#19=SECURITY_CLASSIFICATION(' ',' ',#18) ; +#18=SECURITY_CLASSIFICATION_LEVEL('unclassified') ; +#63=CARTESIAN_POINT('Axis2P3D Location',(146.885775404,5.,0.)) ; +#68=CARTESIAN_POINT('Line Origine',(146.885775404,5.,5.)) ; +#72=CARTESIAN_POINT('Vertex',(30.0000000004,5.,5.)) ; +#74=CARTESIAN_POINT('Vertex',(20.0000000004,5.,5.)) ; +#78=CARTESIAN_POINT('Control Point',(30.,5.,-5.)) ; +#79=CARTESIAN_POINT('Control Point',(30.,4.2146018366,-5.)) ; +#80=CARTESIAN_POINT('Control Point',(30.,3.42920367321,-4.84578743123)) ; +#81=CARTESIAN_POINT('Control Point',(30.0000000001,2.68423158173,-4.53720988735)) ; +#82=CARTESIAN_POINT('Control Point',(30.0000000001,1.35542134095,-3.64457865905)) ; +#83=CARTESIAN_POINT('Control Point',(30.0000000002,0.462790112647,-2.31576841827)) ; +#84=CARTESIAN_POINT('Control Point',(30.0000000002,0.154212568767,-1.57079632679)) ; +#85=CARTESIAN_POINT('Control Point',(30.0000000002,-0.154212568767,1.98447071066E-015)) ; +#86=CARTESIAN_POINT('Control Point',(30.0000000003,0.154212568767,1.57079632679)) ; +#87=CARTESIAN_POINT('Control Point',(30.0000000003,0.462790112647,2.31576841827)) ; +#88=CARTESIAN_POINT('Control Point',(30.0000000003,1.35542134095,3.64457865905)) ; +#89=CARTESIAN_POINT('Control Point',(30.0000000004,2.68423158173,4.53720988735)) ; +#90=CARTESIAN_POINT('Control Point',(30.0000000004,3.42920367321,4.84578743123)) ; +#91=CARTESIAN_POINT('Control Point',(30.0000000004,4.2146018366,5.)) ; +#92=CARTESIAN_POINT('Control Point',(30.0000000004,5.,5.)) ; +#93=CARTESIAN_POINT('Vertex',(30.0000000004,5.,-5.)) ; +#96=CARTESIAN_POINT('Line Origine',(146.885775404,5.,-5.)) ; +#100=CARTESIAN_POINT('Vertex',(20.,5.,-5.)) ; +#104=CARTESIAN_POINT('Control Point',(20.0000000004,5.,5.)) ; +#105=CARTESIAN_POINT('Control Point',(20.0000000004,4.2146018366,5.)) ; +#106=CARTESIAN_POINT('Control Point',(20.0000000004,3.42920367321,4.84578743123)) ; +#107=CARTESIAN_POINT('Control Point',(20.0000000004,2.68423158173,4.53720988735)) ; +#108=CARTESIAN_POINT('Control Point',(20.0000000003,1.35542134095,3.64457865905)) ; +#109=CARTESIAN_POINT('Control Point',(20.0000000003,0.462790112647,2.31576841827)) ; +#110=CARTESIAN_POINT('Control Point',(20.0000000003,0.154212568767,1.57079632679)) ; +#111=CARTESIAN_POINT('Control Point',(20.0000000002,-0.154212568767,-1.13398326323E-015)) ; +#112=CARTESIAN_POINT('Control Point',(20.0000000002,0.154212568767,-1.57079632679)) ; +#113=CARTESIAN_POINT('Control Point',(20.0000000002,0.462790112647,-2.31576841827)) ; +#114=CARTESIAN_POINT('Control Point',(20.0000000001,1.35542134095,-3.64457865905)) ; +#115=CARTESIAN_POINT('Control Point',(20.0000000001,2.68423158173,-4.53720988735)) ; +#116=CARTESIAN_POINT('Control Point',(20.,3.42920367321,-4.84578743123)) ; +#117=CARTESIAN_POINT('Control Point',(20.,4.2146018366,-5.)) ; +#118=CARTESIAN_POINT('Control Point',(20.,5.,-5.)) ; +#127=CARTESIAN_POINT('Axis2P3D Location',(146.885775404,5.,0.)) ; +#132=CARTESIAN_POINT('Axis2P3D Location',(20.0000000004,5.,0.)) ; +#137=CARTESIAN_POINT('Axis2P3D Location',(30.0000000004,5.,0.)) ; +#149=CARTESIAN_POINT('Axis2P3D Location',(30.,25.,-50.)) ; +#154=CARTESIAN_POINT('Line Origine',(30.,0.,50.)) ; +#158=CARTESIAN_POINT('Vertex',(30.,25.,50.)) ; +#160=CARTESIAN_POINT('Vertex',(30.,-25.,50.)) ; +#163=CARTESIAN_POINT('Line Origine',(30.,-25.,0.)) ; +#167=CARTESIAN_POINT('Vertex',(30.,-25.,-50.)) ; +#170=CARTESIAN_POINT('Line Origine',(30.,0.,-50.)) ; +#174=CARTESIAN_POINT('Vertex',(30.,25.,-50.)) ; +#177=CARTESIAN_POINT('Line Origine',(30.,25.,0.)) ; +#189=CARTESIAN_POINT('Control Point',(30.,-13.1698729806,15.4903810564)) ; +#190=CARTESIAN_POINT('Control Point',(30.,-12.8960161287,15.016047075)) ; +#191=CARTESIAN_POINT('Control Point',(30.,-12.6871093474,14.5042147651)) ; +#192=CARTESIAN_POINT('Control Point',(30.,-12.5500072729,13.9666921033)) ; +#193=CARTESIAN_POINT('Control Point',(30.,-12.4264790799,12.8679642662)) ; +#194=CARTESIAN_POINT('Control Point',(30.,-12.6028538506,11.7764747485)) ; +#195=CARTESIAN_POINT('Control Point',(30.,-12.7657199312,11.2461897012)) ; +#196=CARTESIAN_POINT('Control Point',(30.,-13.2324186028,10.2438651882)) ; +#197=CARTESIAN_POINT('Control Point',(30.,-13.9513789308,9.40389287983)) ; +#198=CARTESIAN_POINT('Control Point',(30.,-14.366562681,9.0359933905)) ; +#199=CARTESIAN_POINT('Control Point',(30.,-15.2869440429,8.42332689458)) ; +#200=CARTESIAN_POINT('Control Point',(30.,-16.3381404003,8.08062635872)) ; +#201=CARTESIAN_POINT('Control Point',(30.,-16.8841695996,7.98275046179)) ; +#202=CARTESIAN_POINT('Control Point',(30.,-17.9889534405,7.93899264059)) ; +#203=CARTESIAN_POINT('Control Point',(30.,-19.06483247,8.1938293503)) ; +#204=CARTESIAN_POINT('Control Point',(30.,-19.5819528563,8.39461305141)) ; +#205=CARTESIAN_POINT('Control Point',(30.,-20.4202785222,8.86148802385)) ; +#206=CARTESIAN_POINT('Control Point',(30.,-21.1229012492,9.50902773031)) ; +#207=CARTESIAN_POINT('Control Point',(30.,-21.3919903062,9.81270158389)) ; +#208=CARTESIAN_POINT('Control Point',(30.,-21.6286380923,10.1413919975)) ; +#209=CARTESIAN_POINT('Control Point',(30.,-21.8301270194,10.4903810564)) ; +#210=CARTESIAN_POINT('Vertex',(30.0000000004,-13.1698729811,15.4903810568)) ; +#212=CARTESIAN_POINT('Vertex',(30.0000000004,-21.8301270189,10.4903810568)) ; +#216=CARTESIAN_POINT('Control Point',(30.,-21.8301270194,10.4903810564)) ; +#217=CARTESIAN_POINT('Control Point',(30.,-22.103983871,10.9647150374)) ; +#218=CARTESIAN_POINT('Control Point',(30.,-22.3128906521,11.4765473467)) ; +#219=CARTESIAN_POINT('Control Point',(30.,-22.4499927272,12.0140700109)) ; +#220=CARTESIAN_POINT('Control Point',(30.,-22.57352092,13.112797848)) ; +#221=CARTESIAN_POINT('Control Point',(30.,-22.3971461491,14.2042873658)) ; +#222=CARTESIAN_POINT('Control Point',(30.,-22.2342800694,14.7345724105)) ; +#223=CARTESIAN_POINT('Control Point',(30.,-21.767581398,15.7368969234)) ; +#224=CARTESIAN_POINT('Control Point',(30.,-21.0486210703,16.5768692318)) ; +#225=CARTESIAN_POINT('Control Point',(30.,-20.6334373176,16.9447687251)) ; +#226=CARTESIAN_POINT('Control Point',(30.,-19.7130559573,17.5574352198)) ; +#227=CARTESIAN_POINT('Control Point',(30.,-18.6618596017,17.9001357554)) ; +#228=CARTESIAN_POINT('Control Point',(30.,-18.1158303983,17.9980116512)) ; +#229=CARTESIAN_POINT('Control Point',(30.,-17.0110465561,18.0417694721)) ; +#230=CARTESIAN_POINT('Control Point',(30.,-15.9351675255,17.7869327615)) ; +#231=CARTESIAN_POINT('Control Point',(30.,-15.4180471478,17.5861490638)) ; +#232=CARTESIAN_POINT('Control Point',(30.,-14.5797214775,17.1192740895)) ; +#233=CARTESIAN_POINT('Control Point',(30.,-13.8770987475,16.4717343795)) ; +#234=CARTESIAN_POINT('Control Point',(30.,-13.6080096965,16.1680605327)) ; +#235=CARTESIAN_POINT('Control Point',(30.,-13.3713619088,15.8393701173)) ; +#236=CARTESIAN_POINT('Control Point',(30.,-13.1698729806,15.4903810564)) ; +#243=CARTESIAN_POINT('Control Point',(30.,-21.8301270194,-10.4903810564)) ; +#244=CARTESIAN_POINT('Control Point',(30.,-21.5562701677,-10.0160470753)) ; +#245=CARTESIAN_POINT('Control Point',(30.,-21.2174637758,-9.57921234104)) ; +#246=CARTESIAN_POINT('Control Point',(30.,-20.8205065314,-9.19171712959)) ; +#247=CARTESIAN_POINT('Control Point',(30.,-19.9307444093,-8.53537465804)) ; +#248=CARTESIAN_POINT('Control Point',(30.,-18.8972993738,-8.14237493132)) ; +#249=CARTESIAN_POINT('Control Point',(30.,-18.3566260127,-8.01827857092)) ; +#250=CARTESIAN_POINT('Control Point',(30.,-17.2552381873,-7.92128922002)) ; +#251=CARTESIAN_POINT('Control Point',(30.,-16.1683206673,-8.12394097344)) ; +#252=CARTESIAN_POINT('Control Point',(30.,-15.6421184809,-8.29955090444)) ; +#253=CARTESIAN_POINT('Control Point',(30.,-14.651343053,-8.79029129626)) ; +#254=CARTESIAN_POINT('Control Point',(30.,-13.8289575062,-9.52930377634)) ; +#255=CARTESIAN_POINT('Control Point',(30.,-13.4711798922,-9.95324098914)) ; +#256=CARTESIAN_POINT('Control Point',(30.,-12.8808925865,-10.8881329516)) ; +#257=CARTESIAN_POINT('Control Point',(30.,-12.5636481364,-11.9472898787)) ; +#258=CARTESIAN_POINT('Control Point',(30.,-12.4789717295,-12.4955211137)) ; +#259=CARTESIAN_POINT('Control Point',(30.,-12.4641344825,-13.4549699256)) ; +#260=CARTESIAN_POINT('Control Point',(30.,-12.6736089554,-14.3872289119)) ; +#261=CARTESIAN_POINT('Control Point',(30.,-12.8020536981,-14.7721037957)) ; +#262=CARTESIAN_POINT('Control Point',(30.,-12.9683840533,-15.1413919973)) ; +#263=CARTESIAN_POINT('Control Point',(30.,-13.1698729806,-15.4903810564)) ; +#264=CARTESIAN_POINT('Vertex',(30.0000000004,-21.8301270189,-10.4903810568)) ; +#266=CARTESIAN_POINT('Vertex',(30.0000000004,-13.1698729811,-15.4903810568)) ; +#270=CARTESIAN_POINT('Control Point',(30.,-13.1698729806,-15.4903810564)) ; +#271=CARTESIAN_POINT('Control Point',(30.,-13.4437298331,-15.9647150391)) ; +#272=CARTESIAN_POINT('Control Point',(30.,-13.7825362263,-16.4015497746)) ; +#273=CARTESIAN_POINT('Control Point',(30.,-14.1794934657,-16.7890449812)) ; +#274=CARTESIAN_POINT('Control Point',(30.,-15.069255591,-17.4453874557)) ; +#275=CARTESIAN_POINT('Control Point',(30.,-16.1027006308,-17.8383871833)) ; +#276=CARTESIAN_POINT('Control Point',(30.,-16.6433739825,-17.9624835415)) ; +#277=CARTESIAN_POINT('Control Point',(30.,-17.7447618126,-18.0594728935)) ; +#278=CARTESIAN_POINT('Control Point',(30.,-18.8316793374,-17.8568211386)) ; +#279=CARTESIAN_POINT('Control Point',(30.,-19.3578815148,-17.6812112106)) ; +#280=CARTESIAN_POINT('Control Point',(30.,-20.3486569466,-17.1904708175)) ; +#281=CARTESIAN_POINT('Control Point',(30.,-21.1710424963,-16.4514583344)) ; +#282=CARTESIAN_POINT('Control Point',(30.,-21.528820106,-16.0275211265)) ; +#283=CARTESIAN_POINT('Control Point',(30.,-22.1191074132,-15.0926291625)) ; +#284=CARTESIAN_POINT('Control Point',(30.,-22.4363518638,-14.0334722334)) ; +#285=CARTESIAN_POINT('Control Point',(30.,-22.5210282705,-13.485241)) ; +#286=CARTESIAN_POINT('Control Point',(30.,-22.5358655175,-12.5257921888)) ; +#287=CARTESIAN_POINT('Control Point',(30.,-22.3263910451,-11.5935332031)) ; +#288=CARTESIAN_POINT('Control Point',(30.,-22.197946301,-11.2086583152)) ; +#289=CARTESIAN_POINT('Control Point',(30.,-22.0316159461,-10.8393701146)) ; +#290=CARTESIAN_POINT('Control Point',(30.,-21.8301270194,-10.4903810564)) ; +#301=CARTESIAN_POINT('Axis2P3D Location',(20.,-25.,-50.)) ; +#306=CARTESIAN_POINT('Line Origine',(20.,-5.,50.)) ; +#310=CARTESIAN_POINT('Vertex',(20.,-25.,50.)) ; +#312=CARTESIAN_POINT('Vertex',(20.,15.,50.)) ; +#315=CARTESIAN_POINT('Line Origine',(20.,15.,0.)) ; +#319=CARTESIAN_POINT('Vertex',(20.,15.,-50.)) ; +#322=CARTESIAN_POINT('Line Origine',(20.,-5.,-50.)) ; +#326=CARTESIAN_POINT('Vertex',(20.,-25.,-50.)) ; +#329=CARTESIAN_POINT('Line Origine',(20.,-25.,0.)) ; +#341=CARTESIAN_POINT('Control Point',(20.,-21.8301270194,10.4903810564)) ; +#342=CARTESIAN_POINT('Control Point',(20.,-21.5562701677,10.0160470753)) ; +#343=CARTESIAN_POINT('Control Point',(20.,-21.2174637758,9.57921234103)) ; +#344=CARTESIAN_POINT('Control Point',(20.,-20.8205065314,9.1917171296)) ; +#345=CARTESIAN_POINT('Control Point',(20.,-19.9307444093,8.53537465804)) ; +#346=CARTESIAN_POINT('Control Point',(20.,-18.8972993738,8.14237493132)) ; +#347=CARTESIAN_POINT('Control Point',(20.,-18.3566260127,8.01827857092)) ; +#348=CARTESIAN_POINT('Control Point',(20.,-17.2552381874,7.92128922002)) ; +#349=CARTESIAN_POINT('Control Point',(20.,-16.1683206673,8.12394097343)) ; +#350=CARTESIAN_POINT('Control Point',(20.,-15.6421184809,8.29955090444)) ; +#351=CARTESIAN_POINT('Control Point',(20.,-14.651343053,8.79029129627)) ; +#352=CARTESIAN_POINT('Control Point',(20.,-13.8289575061,9.52930377635)) ; +#353=CARTESIAN_POINT('Control Point',(20.,-13.4711798922,9.95324098912)) ; +#354=CARTESIAN_POINT('Control Point',(20.,-12.8808925865,10.8881329516)) ; +#355=CARTESIAN_POINT('Control Point',(20.,-12.5636481364,11.9472898788)) ; +#356=CARTESIAN_POINT('Control Point',(20.,-12.4789717295,12.4955211137)) ; +#357=CARTESIAN_POINT('Control Point',(20.,-12.4641344825,13.4549699256)) ; +#358=CARTESIAN_POINT('Control Point',(20.,-12.6736089554,14.3872289119)) ; +#359=CARTESIAN_POINT('Control Point',(20.,-12.8020536981,14.7721037957)) ; +#360=CARTESIAN_POINT('Control Point',(20.,-12.9683840533,15.1413919973)) ; +#361=CARTESIAN_POINT('Control Point',(20.,-13.1698729806,15.4903810564)) ; +#362=CARTESIAN_POINT('Vertex',(20.0000000004,-21.8301270189,10.4903810568)) ; +#364=CARTESIAN_POINT('Vertex',(20.,-13.1698729811,15.4903810568)) ; +#368=CARTESIAN_POINT('Control Point',(20.,-13.1698729806,15.4903810564)) ; +#369=CARTESIAN_POINT('Control Point',(20.,-13.4437298332,15.9647150391)) ; +#370=CARTESIAN_POINT('Control Point',(20.,-13.7825362264,16.4015497747)) ; +#371=CARTESIAN_POINT('Control Point',(20.,-14.1794934656,16.7890449811)) ; +#372=CARTESIAN_POINT('Control Point',(20.,-15.069255591,17.4453874556)) ; +#373=CARTESIAN_POINT('Control Point',(20.,-16.1027006308,17.8383871833)) ; +#374=CARTESIAN_POINT('Control Point',(20.,-16.6433739825,17.9624835415)) ; +#375=CARTESIAN_POINT('Control Point',(20.,-17.7447618126,18.0594728935)) ; +#376=CARTESIAN_POINT('Control Point',(20.,-18.8316793374,17.8568211386)) ; +#377=CARTESIAN_POINT('Control Point',(20.,-19.3578815148,17.6812112106)) ; +#378=CARTESIAN_POINT('Control Point',(20.,-20.3486569467,17.1904708175)) ; +#379=CARTESIAN_POINT('Control Point',(20.,-21.1710424963,16.4514583344)) ; +#380=CARTESIAN_POINT('Control Point',(20.,-21.528820106,16.0275211265)) ; +#381=CARTESIAN_POINT('Control Point',(20.,-22.1191074132,15.0926291625)) ; +#382=CARTESIAN_POINT('Control Point',(20.,-22.4363518638,14.0334722334)) ; +#383=CARTESIAN_POINT('Control Point',(20.,-22.5210282705,13.485241)) ; +#384=CARTESIAN_POINT('Control Point',(20.,-22.5358655175,12.5257921888)) ; +#385=CARTESIAN_POINT('Control Point',(20.,-22.3263910451,11.5935332031)) ; +#386=CARTESIAN_POINT('Control Point',(20.,-22.197946301,11.2086583152)) ; +#387=CARTESIAN_POINT('Control Point',(20.,-22.0316159461,10.8393701146)) ; +#388=CARTESIAN_POINT('Control Point',(20.,-21.8301270194,10.4903810564)) ; +#395=CARTESIAN_POINT('Control Point',(20.,-13.1698729806,-15.4903810564)) ; +#396=CARTESIAN_POINT('Control Point',(20.,-12.8960161287,-15.016047075)) ; +#397=CARTESIAN_POINT('Control Point',(20.,-12.6871093474,-14.5042147651)) ; +#398=CARTESIAN_POINT('Control Point',(20.,-12.5500072729,-13.9666921032)) ; +#399=CARTESIAN_POINT('Control Point',(20.,-12.4264790799,-12.8679642662)) ; +#400=CARTESIAN_POINT('Control Point',(20.,-12.6028538506,-11.7764747485)) ; +#401=CARTESIAN_POINT('Control Point',(20.,-12.7657199312,-11.2461897011)) ; +#402=CARTESIAN_POINT('Control Point',(20.,-13.2324186028,-10.2438651882)) ; +#403=CARTESIAN_POINT('Control Point',(20.,-13.9513789308,-9.40389287982)) ; +#404=CARTESIAN_POINT('Control Point',(20.,-14.366562681,-9.0359933905)) ; +#405=CARTESIAN_POINT('Control Point',(20.,-15.2869440429,-8.42332689458)) ; +#406=CARTESIAN_POINT('Control Point',(20.,-16.3381404003,-8.08062635872)) ; +#407=CARTESIAN_POINT('Control Point',(20.,-16.8841695996,-7.98275046179)) ; +#408=CARTESIAN_POINT('Control Point',(20.,-17.9889534405,-7.93899264059)) ; +#409=CARTESIAN_POINT('Control Point',(20.,-19.06483247,-8.1938293503)) ; +#410=CARTESIAN_POINT('Control Point',(20.,-19.5819528563,-8.39461305141)) ; +#411=CARTESIAN_POINT('Control Point',(20.,-20.4202785222,-8.86148802385)) ; +#412=CARTESIAN_POINT('Control Point',(20.,-21.1229012492,-9.50902773031)) ; +#413=CARTESIAN_POINT('Control Point',(20.,-21.3919903062,-9.81270158389)) ; +#414=CARTESIAN_POINT('Control Point',(20.,-21.6286380923,-10.1413919975)) ; +#415=CARTESIAN_POINT('Control Point',(20.,-21.8301270194,-10.4903810564)) ; +#416=CARTESIAN_POINT('Vertex',(20.0000000004,-13.1698729811,-15.4903810568)) ; +#418=CARTESIAN_POINT('Vertex',(20.,-21.8301270189,-10.4903810568)) ; +#422=CARTESIAN_POINT('Control Point',(20.,-21.8301270194,-10.4903810564)) ; +#423=CARTESIAN_POINT('Control Point',(20.,-22.103983871,-10.9647150374)) ; +#424=CARTESIAN_POINT('Control Point',(20.,-22.3128906521,-11.4765473467)) ; +#425=CARTESIAN_POINT('Control Point',(20.,-22.4499927272,-12.0140700109)) ; +#426=CARTESIAN_POINT('Control Point',(20.,-22.57352092,-13.112797848)) ; +#427=CARTESIAN_POINT('Control Point',(20.,-22.3971461491,-14.2042873658)) ; +#428=CARTESIAN_POINT('Control Point',(20.,-22.2342800694,-14.7345724104)) ; +#429=CARTESIAN_POINT('Control Point',(20.,-21.767581398,-15.7368969234)) ; +#430=CARTESIAN_POINT('Control Point',(20.,-21.0486210703,-16.5768692318)) ; +#431=CARTESIAN_POINT('Control Point',(20.,-20.6334373176,-16.9447687252)) ; +#432=CARTESIAN_POINT('Control Point',(20.,-19.7130559572,-17.5574352198)) ; +#433=CARTESIAN_POINT('Control Point',(20.,-18.6618596017,-17.9001357554)) ; +#434=CARTESIAN_POINT('Control Point',(20.,-18.1158303983,-17.9980116512)) ; +#435=CARTESIAN_POINT('Control Point',(20.,-17.0110465561,-18.0417694721)) ; +#436=CARTESIAN_POINT('Control Point',(20.,-15.9351675255,-17.7869327615)) ; +#437=CARTESIAN_POINT('Control Point',(20.,-15.4180471478,-17.5861490637)) ; +#438=CARTESIAN_POINT('Control Point',(20.,-14.5797214775,-17.1192740895)) ; +#439=CARTESIAN_POINT('Control Point',(20.,-13.8770987475,-16.4717343795)) ; +#440=CARTESIAN_POINT('Control Point',(20.,-13.6080096965,-16.1680605327)) ; +#441=CARTESIAN_POINT('Control Point',(20.,-13.3713619088,-15.8393701173)) ; +#442=CARTESIAN_POINT('Control Point',(20.,-13.1698729806,-15.4903810564)) ; +#453=CARTESIAN_POINT('Axis2P3D Location',(20.,-25.,50.)) ; +#458=CARTESIAN_POINT('Line Origine',(25.,-25.,50.)) ; +#463=CARTESIAN_POINT('Line Origine',(0.,25.,50.)) ; +#467=CARTESIAN_POINT('Vertex',(-30.,25.,50.)) ; +#470=CARTESIAN_POINT('Line Origine',(-30.,20.,50.)) ; +#474=CARTESIAN_POINT('Vertex',(-30.,15.,50.)) ; +#477=CARTESIAN_POINT('Line Origine',(-5.,15.,50.)) ; +#491=CARTESIAN_POINT('Axis2P3D Location',(30.,-25.,-50.)) ; +#496=CARTESIAN_POINT('Line Origine',(25.,-25.,-50.)) ; +#508=CARTESIAN_POINT('Axis2P3D Location',(6.66666666667,5.,-50.)) ; +#513=CARTESIAN_POINT('Line Origine',(-4.99999999938,15.,-50.)) ; +#517=CARTESIAN_POINT('Vertex',(-30.,15.,-50.)) ; +#520=CARTESIAN_POINT('Line Origine',(-29.9999999994,20.,-50.)) ; +#524=CARTESIAN_POINT('Vertex',(-30.,25.,-50.)) ; +#527=CARTESIAN_POINT('Line Origine',(6.20900664217E-010,25.,-50.)) ; +#541=CARTESIAN_POINT('Axis2P3D Location',(-30.,25.,-50.)) ; +#546=CARTESIAN_POINT('Line Origine',(-30.,25.,0.)) ; +#558=CARTESIAN_POINT('Control Point',(-10.,25.,5.)) ; +#559=CARTESIAN_POINT('Control Point',(-10.5477137052,25.,5.)) ; +#560=CARTESIAN_POINT('Control Point',(-11.09542688,25.,4.9250024243)) ; +#561=CARTESIAN_POINT('Control Point',(-11.6294861924,25.,4.77497497429)) ; +#562=CARTESIAN_POINT('Control Point',(-12.642776511,25.,4.33258960796)) ; +#563=CARTESIAN_POINT('Control Point',(-13.4998467783,25.,3.63409981446)) ; +#564=CARTESIAN_POINT('Control Point',(-13.8776540543,25.,3.2279111336)) ; +#565=CARTESIAN_POINT('Control Point',(-14.5123432122,25.,2.32257596885)) ; +#566=CARTESIAN_POINT('Control Point',(-14.8803004065,25.,1.27995190258)) ; +#567=CARTESIAN_POINT('Control Point',(-14.9913188347,25.,0.736442489121)) ; +#568=CARTESIAN_POINT('Control Point',(-15.0617129038,25.,-0.366964399168)) ; +#569=CARTESIAN_POINT('Control Point',(-14.8329020956,25.,-1.44867741682)) ; +#570=CARTESIAN_POINT('Control Point',(-14.6446505074,25.,-1.97049052935)) ; +#571=CARTESIAN_POINT('Control Point',(-14.1301539728,25.,-2.94914030862)) ; +#572=CARTESIAN_POINT('Control Point',(-13.3715193963,25.,-3.75346052241)) ; +#573=CARTESIAN_POINT('Control Point',(-12.9390754118,25.,-4.10090806785)) ; +#574=CARTESIAN_POINT('Control Point',(-12.1155869935,25.,-4.59348190386)) ; +#575=CARTESIAN_POINT('Control Point',(-11.2034897956,25.,-4.87820118104)) ; +#576=CARTESIAN_POINT('Control Point',(-10.8059559954,25.,-4.95940221226)) ; +#577=CARTESIAN_POINT('Control Point',(-10.4029778542,25.,-5.)) ; +#578=CARTESIAN_POINT('Control Point',(-10.,25.,-5.)) ; +#579=CARTESIAN_POINT('Vertex',(-10.,25.0000000004,5.)) ; +#581=CARTESIAN_POINT('Vertex',(-10.,25.0000000004,-5.)) ; +#585=CARTESIAN_POINT('Control Point',(-10.,25.,-5.)) ; +#586=CARTESIAN_POINT('Control Point',(-9.45228629483,25.,-5.)) ; +#587=CARTESIAN_POINT('Control Point',(-8.90457311998,25.,-4.92500242429)) ; +#588=CARTESIAN_POINT('Control Point',(-8.37051380756,25.,-4.77497497429)) ; +#589=CARTESIAN_POINT('Control Point',(-7.35722348901,25.,-4.33258960796)) ; +#590=CARTESIAN_POINT('Control Point',(-6.5001532217,25.,-3.63409981447)) ; +#591=CARTESIAN_POINT('Control Point',(-6.12234594572,25.,-3.22791113359)) ; +#592=CARTESIAN_POINT('Control Point',(-5.48765678784,25.,-2.32257596885)) ; +#593=CARTESIAN_POINT('Control Point',(-5.11969959348,25.,-1.27995190257)) ; +#594=CARTESIAN_POINT('Control Point',(-5.00868116525,25.,-0.736442489123)) ; +#595=CARTESIAN_POINT('Control Point',(-4.93828709623,25.,0.366964399184)) ; +#596=CARTESIAN_POINT('Control Point',(-5.16709790445,25.,1.44867741685)) ; +#597=CARTESIAN_POINT('Control Point',(-5.3553494926,25.,1.97049052932)) ; +#598=CARTESIAN_POINT('Control Point',(-5.86984602717,25.,2.94914030863)) ; +#599=CARTESIAN_POINT('Control Point',(-6.6284806037,25.,3.75346052244)) ; +#600=CARTESIAN_POINT('Control Point',(-7.06092458818,25.,4.10090806783)) ; +#601=CARTESIAN_POINT('Control Point',(-7.88441300652,25.,4.59348190386)) ; +#602=CARTESIAN_POINT('Control Point',(-8.79651020437,25.,4.87820118104)) ; +#603=CARTESIAN_POINT('Control Point',(-9.19404400457,25.,4.95940221226)) ; +#604=CARTESIAN_POINT('Control Point',(-9.59702214582,25.,5.)) ; +#605=CARTESIAN_POINT('Control Point',(-10.,25.,5.)) ; +#612=CARTESIAN_POINT('Axis2P3D Location',(146.885775404,-17.5,12.9903810568)) ; +#617=CARTESIAN_POINT('Line Origine',(146.885775404,-21.8301270189,10.4903810568)) ; +#622=CARTESIAN_POINT('Line Origine',(146.885775404,-13.1698729811,15.4903810568)) ; +#634=CARTESIAN_POINT('Axis2P3D Location',(146.885775404,-17.5,12.9903810568)) ; +#646=CARTESIAN_POINT('Axis2P3D Location',(146.885775404,-17.5,-12.9903810568)) ; +#651=CARTESIAN_POINT('Line Origine',(146.885775404,-13.1698729811,-15.4903810568)) ; +#656=CARTESIAN_POINT('Line Origine',(146.885775404,-21.8301270189,-10.4903810568)) ; +#668=CARTESIAN_POINT('Axis2P3D Location',(146.885775404,-17.5,-12.9903810568)) ; +#680=CARTESIAN_POINT('Axis2P3D Location',(20.,15.,-50.)) ; +#685=CARTESIAN_POINT('Line Origine',(-30.,15.,0.)) ; +#697=CARTESIAN_POINT('Control Point',(-10.,15.,-5.)) ; +#698=CARTESIAN_POINT('Control Point',(-10.5477137052,15.,-5.)) ; +#699=CARTESIAN_POINT('Control Point',(-11.0954268801,15.,-4.92500242428)) ; +#700=CARTESIAN_POINT('Control Point',(-11.6294861924,15.,-4.77497497432)) ; +#701=CARTESIAN_POINT('Control Point',(-12.642776511,15.,-4.33258960797)) ; +#702=CARTESIAN_POINT('Control Point',(-13.4998467783,15.,-3.63409981443)) ; +#703=CARTESIAN_POINT('Control Point',(-13.8776540542,15.,-3.22791113364)) ; +#704=CARTESIAN_POINT('Control Point',(-14.5123432122,15.,-2.32257596888)) ; +#705=CARTESIAN_POINT('Control Point',(-14.8803004065,15.,-1.27995190258)) ; +#706=CARTESIAN_POINT('Control Point',(-14.9913188347,15.,-0.736442489115)) ; +#707=CARTESIAN_POINT('Control Point',(-15.0617129038,15.,0.366964399197)) ; +#708=CARTESIAN_POINT('Control Point',(-14.8329020955,15.,1.44867741687)) ; +#709=CARTESIAN_POINT('Control Point',(-14.6446505074,15.,1.97049052931)) ; +#710=CARTESIAN_POINT('Control Point',(-14.1301539728,15.,2.94914030861)) ; +#711=CARTESIAN_POINT('Control Point',(-13.3715193963,15.,3.75346052243)) ; +#712=CARTESIAN_POINT('Control Point',(-12.9390754118,15.,4.10090806784)) ; +#713=CARTESIAN_POINT('Control Point',(-12.1155869935,15.,4.59348190386)) ; +#714=CARTESIAN_POINT('Control Point',(-11.2034897956,15.,4.87820118104)) ; +#715=CARTESIAN_POINT('Control Point',(-10.8059559954,15.,4.95940221226)) ; +#716=CARTESIAN_POINT('Control Point',(-10.4029778542,15.,5.)) ; +#717=CARTESIAN_POINT('Control Point',(-10.,15.,5.)) ; +#718=CARTESIAN_POINT('Vertex',(-10.,15.0000000004,-5.)) ; +#720=CARTESIAN_POINT('Vertex',(-10.,15.,5.)) ; +#724=CARTESIAN_POINT('Control Point',(-10.,15.,5.)) ; +#725=CARTESIAN_POINT('Control Point',(-9.45228629483,15.,5.)) ; +#726=CARTESIAN_POINT('Control Point',(-8.90457311998,15.,4.9250024243)) ; +#727=CARTESIAN_POINT('Control Point',(-8.37051380755,15.,4.77497497429)) ; +#728=CARTESIAN_POINT('Control Point',(-7.35722348899,15.,4.33258960795)) ; +#729=CARTESIAN_POINT('Control Point',(-6.50015322168,15.,3.63409981445)) ; +#730=CARTESIAN_POINT('Control Point',(-6.12234594573,15.,3.22791113361)) ; +#731=CARTESIAN_POINT('Control Point',(-5.48765678784,15.,2.32257596886)) ; +#732=CARTESIAN_POINT('Control Point',(-5.11969959348,15.,1.27995190258)) ; +#733=CARTESIAN_POINT('Control Point',(-5.00868116525,15.,0.736442489116)) ; +#734=CARTESIAN_POINT('Control Point',(-4.93828709623,15.,-0.366964399172)) ; +#735=CARTESIAN_POINT('Control Point',(-5.16709790445,15.,-1.44867741682)) ; +#736=CARTESIAN_POINT('Control Point',(-5.35534949262,15.,-1.97049052936)) ; +#737=CARTESIAN_POINT('Control Point',(-5.86984602718,15.,-2.94914030863)) ; +#738=CARTESIAN_POINT('Control Point',(-6.62848060368,15.,-3.75346052242)) ; +#739=CARTESIAN_POINT('Control Point',(-7.06092458819,15.,-4.10090806784)) ; +#740=CARTESIAN_POINT('Control Point',(-7.88441300653,15.,-4.59348190386)) ; +#741=CARTESIAN_POINT('Control Point',(-8.79651020436,15.,-4.87820118104)) ; +#742=CARTESIAN_POINT('Control Point',(-9.19404400458,15.,-4.95940221226)) ; +#743=CARTESIAN_POINT('Control Point',(-9.59702214582,15.,-5.)) ; +#744=CARTESIAN_POINT('Control Point',(-10.,15.,-5.)) ; +#751=CARTESIAN_POINT('Axis2P3D Location',(-30.,15.,-50.)) ; +#763=CARTESIAN_POINT('Axis2P3D Location',(-10.,141.885775404,0.)) ; +#768=CARTESIAN_POINT('Line Origine',(-10.,141.885775404,-5.)) ; +#773=CARTESIAN_POINT('Line Origine',(-10.,141.885775404,5.)) ; +#785=CARTESIAN_POINT('Axis2P3D Location',(-10.,141.885775404,0.)) ; +#807=CARTESIAN_POINT('NONE',(0.,0.,0.)) ; +#808=CARTESIAN_POINT('NONE',(150.,75.,50.)) ; +#832=CARTESIAN_POINT('Axis2P3D Location',(1.5,1.006602E-014,1.746751E-014)) ; +#837=CARTESIAN_POINT('Axis2P3D Location',(1.5,1.13982876296E-014,1.61352423704E-014)) ; +#841=CARTESIAN_POINT('Vertex',(1.5,7.5,0.)) ; +#843=CARTESIAN_POINT('Vertex',(1.5,-7.5,-4.24912383924E-015)) ; +#846=CARTESIAN_POINT('Axis2P3D Location',(1.5,8.73375237045E-015,1.87997776296E-014)) ; +#855=CARTESIAN_POINT('Axis2P3D Location',(1.5,1.09541984197E-014,1.65793315803E-014)) ; +#859=CARTESIAN_POINT('Vertex',(1.5,5.,0.)) ; +#861=CARTESIAN_POINT('Vertex',(1.5,-5.,6.12303176911E-016)) ; +#864=CARTESIAN_POINT('Axis2P3D Location',(1.5,9.1778415803E-015,1.83556884197E-014)) ; +#874=CARTESIAN_POINT('Axis2P3D Location',(1.5,0.,0.)) ; +#879=CARTESIAN_POINT('Line Origine',(1.5,5.,-1.22460635382E-015)) ; +#883=CARTESIAN_POINT('Vertex',(38.5,5.,0.)) ; +#886=CARTESIAN_POINT('Axis2P3D Location',(38.5,0.,0.)) ; +#890=CARTESIAN_POINT('Vertex',(38.5,-5.,6.12303176911E-016)) ; +#893=CARTESIAN_POINT('Line Origine',(1.5,-5.,6.12303176911E-016)) ; +#905=CARTESIAN_POINT('Axis2P3D Location',(1.5,0.,0.)) ; +#910=CARTESIAN_POINT('Axis2P3D Location',(38.5,0.,0.)) ; +#922=CARTESIAN_POINT('Axis2P3D Location',(38.5,5.,0.)) ; +#932=CARTESIAN_POINT('Axis2P3D Location',(1.5,0.,0.)) ; +#937=CARTESIAN_POINT('Line Origine',(1.5,7.5,0.)) ; +#941=CARTESIAN_POINT('Vertex',(0.5,7.5,0.)) ; +#944=CARTESIAN_POINT('Line Origine',(1.5,-7.5,-4.24912383924E-015)) ; +#948=CARTESIAN_POINT('Vertex',(0.5,-7.5,-4.24912383924E-015)) ; +#951=CARTESIAN_POINT('Axis2P3D Location',(0.5,0.,0.)) ; +#963=CARTESIAN_POINT('Axis2P3D Location',(1.5,0.,0.)) ; +#968=CARTESIAN_POINT('Axis2P3D Location',(0.5,0.,0.)) ; +#980=CARTESIAN_POINT('Axis2P3D Location',(-1.5,7.5,0.)) ; +#985=CARTESIAN_POINT('Axis2P3D Location',(-1.5,0.,-2.53269627493E-015)) ; +#989=CARTESIAN_POINT('Vertex',(-1.5,5.5,7.7538984584E-008)) ; +#991=CARTESIAN_POINT('Vertex',(-1.5,-5.5,-9.61987094331E-008)) ; +#994=CARTESIAN_POINT('Axis2P3D Location',(-1.5,8.881784197E-016,-4.30211422042E-016)) ; +#1004=CARTESIAN_POINT('Axis2P3D Location',(0.5,8.881784197E-016,-3.33066907388E-015)) ; +#1009=CARTESIAN_POINT('Axis2P3D Location',(0.5,5.5,2.74629163854E-009)) ; +#1014=CARTESIAN_POINT('Axis2P3D Location',(0.5,-5.5,-9.6198709526E-008)) ; +#1026=CARTESIAN_POINT('Axis2P3D Location',(0.5,4.4408920985E-016,-1.55431223448E-015)) ; +#1048=CARTESIAN_POINT('NONE',(0.,0.,0.)) ; +#1049=CARTESIAN_POINT('NONE',(252.527291545,67.3529469863,18.9365794127)) ; +#1065=CARTESIAN_POINT('Axis2P3D Location',(-1.5,-7.5,-10.)) ; +#1070=CARTESIAN_POINT('Line Origine',(-1.5,0.,-10.)) ; +#1074=CARTESIAN_POINT('Vertex',(-1.5,-7.5,-10.)) ; +#1076=CARTESIAN_POINT('Vertex',(-1.5,7.5,-10.)) ; +#1079=CARTESIAN_POINT('Line Origine',(-1.5,-7.5,0.)) ; +#1083=CARTESIAN_POINT('Vertex',(-1.5,-7.5,10.)) ; +#1086=CARTESIAN_POINT('Line Origine',(-1.5,0.,10.)) ; +#1090=CARTESIAN_POINT('Vertex',(-1.5,7.5,10.)) ; +#1093=CARTESIAN_POINT('Line Origine',(-1.5,7.5,0.)) ; +#1104=CARTESIAN_POINT('Axis2P3D Location',(-1.5,8.881784197E-016,0.)) ; +#1108=CARTESIAN_POINT('Vertex',(-1.50000000059,8.34347776911E-016,-5.)) ; +#1110=CARTESIAN_POINT('Vertex',(-1.5,2.6645352591E-015,5.)) ; +#1113=CARTESIAN_POINT('Axis2P3D Location',(-1.5,-8.881784197E-016,0.)) ; +#1123=CARTESIAN_POINT('Axis2P3D Location',(1.5,-7.5,-10.)) ; +#1128=CARTESIAN_POINT('Line Origine',(-0.5,-7.5,-10.)) ; +#1132=CARTESIAN_POINT('Vertex',(0.5,-7.5,-10.)) ; +#1135=CARTESIAN_POINT('Line Origine',(-0.5,7.5,-10.)) ; +#1139=CARTESIAN_POINT('Vertex',(0.5,7.5,-10.)) ; +#1142=CARTESIAN_POINT('Line Origine',(0.5,-8.881784197E-016,-10.)) ; +#1154=CARTESIAN_POINT('Axis2P3D Location',(1.5,-7.5,10.)) ; +#1159=CARTESIAN_POINT('Line Origine',(-0.5,-7.5,10.)) ; +#1163=CARTESIAN_POINT('Vertex',(0.5,-7.5,10.)) ; +#1166=CARTESIAN_POINT('Line Origine',(0.5,-7.5,-1.7763568394E-015)) ; +#1178=CARTESIAN_POINT('Axis2P3D Location',(1.5,7.5,10.)) ; +#1183=CARTESIAN_POINT('Line Origine',(-0.5,7.5,10.)) ; +#1187=CARTESIAN_POINT('Vertex',(0.5,7.5,10.)) ; +#1190=CARTESIAN_POINT('Line Origine',(0.5,-1.7763568394E-015,10.)) ; +#1202=CARTESIAN_POINT('Axis2P3D Location',(1.5,7.5,-10.)) ; +#1207=CARTESIAN_POINT('Line Origine',(0.5,7.5,1.7763568394E-015)) ; +#1219=CARTESIAN_POINT('Axis2P3D Location',(0.5,0.,9.)) ; +#1225=CARTESIAN_POINT('Control Point',(1.5,6.5,9.)) ; +#1226=CARTESIAN_POINT('Control Point',(1.5,6.60172877653,9.10172877653)) ; +#1227=CARTESIAN_POINT('Control Point',(1.48706407003,6.70294375782,9.20396816251)) ; +#1228=CARTESIAN_POINT('Control Point',(1.46135276871,6.80390140682,9.30389465826)) ; +#1229=CARTESIAN_POINT('Control Point',(1.38209084822,7.00229313499,9.50228479367)) ; +#1230=CARTESIAN_POINT('Control Point',(1.24254361508,7.18462387437,9.68463244784)) ; +#1231=CARTESIAN_POINT('Control Point',(1.15662240902,7.26921826151,9.76921898666)) ; +#1232=CARTESIAN_POINT('Control Point',(0.987345401215,7.39073963531,9.89073916732)) ; +#1233=CARTESIAN_POINT('Control Point',(0.774983165596,7.46765962756,9.96765992959)) ; +#1234=CARTESIAN_POINT('Control Point',(0.685696192879,7.48922399455,9.98922399452)) ; +#1235=CARTESIAN_POINT('Control Point',(0.592848286934,7.5,10.)) ; +#1236=CARTESIAN_POINT('Control Point',(0.5,7.5,10.)) ; +#1237=CARTESIAN_POINT('Vertex',(1.5,6.5,9.)) ; +#1241=CARTESIAN_POINT('Control Point',(1.5,-6.5,9.)) ; +#1242=CARTESIAN_POINT('Control Point',(1.5,-6.60172877653,9.10172877653)) ; +#1243=CARTESIAN_POINT('Control Point',(1.48706407003,-6.70294375782,9.20396816251)) ; +#1244=CARTESIAN_POINT('Control Point',(1.46135276871,-6.80390140682,9.30389465826)) ; +#1245=CARTESIAN_POINT('Control Point',(1.38209084822,-7.00229313499,9.50228479367)) ; +#1246=CARTESIAN_POINT('Control Point',(1.24254361508,-7.18462387437,9.68463244784)) ; +#1247=CARTESIAN_POINT('Control Point',(1.15662240902,-7.26921826151,9.76921898666)) ; +#1248=CARTESIAN_POINT('Control Point',(0.987345401215,-7.39073963531,9.89073916732)) ; +#1249=CARTESIAN_POINT('Control Point',(0.774983165597,-7.46765962756,9.96765992959)) ; +#1250=CARTESIAN_POINT('Control Point',(0.685696192878,-7.48922399455,9.98922399452)) ; +#1251=CARTESIAN_POINT('Control Point',(0.592848286933,-7.5,10.)) ; +#1252=CARTESIAN_POINT('Control Point',(0.5,-7.5,10.)) ; +#1253=CARTESIAN_POINT('Vertex',(1.5,-6.5,9.)) ; +#1256=CARTESIAN_POINT('Line Origine',(1.5,0.,9.)) ; +#1268=CARTESIAN_POINT('Axis2P3D Location',(0.5,6.5,0.)) ; +#1274=CARTESIAN_POINT('Control Point',(1.5,6.5,-9.)) ; +#1275=CARTESIAN_POINT('Control Point',(1.5,6.60172877653,-9.10172877653)) ; +#1276=CARTESIAN_POINT('Control Point',(1.48706407003,6.70396816251,-9.20294375782)) ; +#1277=CARTESIAN_POINT('Control Point',(1.46135276871,6.80389465826,-9.30390140682)) ; +#1278=CARTESIAN_POINT('Control Point',(1.38209084822,7.00228479367,-9.50229313499)) ; +#1279=CARTESIAN_POINT('Control Point',(1.24254361508,7.18463244784,-9.68462387437)) ; +#1280=CARTESIAN_POINT('Control Point',(1.15662240902,7.26921898666,-9.76921826151)) ; +#1281=CARTESIAN_POINT('Control Point',(0.987345401215,7.39073916732,-9.89073963531)) ; +#1282=CARTESIAN_POINT('Control Point',(0.774983165598,7.46765992959,-9.96765962756)) ; +#1283=CARTESIAN_POINT('Control Point',(0.685696192875,7.48922399452,-9.98922399455)) ; +#1284=CARTESIAN_POINT('Control Point',(0.592848286932,7.5,-10.)) ; +#1285=CARTESIAN_POINT('Control Point',(0.5,7.5,-10.)) ; +#1286=CARTESIAN_POINT('Vertex',(1.5,6.5,-9.)) ; +#1289=CARTESIAN_POINT('Line Origine',(1.5,6.5,0.)) ; +#1301=CARTESIAN_POINT('Axis2P3D Location',(0.5,0.,-9.)) ; +#1307=CARTESIAN_POINT('Control Point',(1.5,-6.5,-9.)) ; +#1308=CARTESIAN_POINT('Control Point',(1.5,-6.60172877653,-9.10172877653)) ; +#1309=CARTESIAN_POINT('Control Point',(1.48706407003,-6.70294375782,-9.20396816251)) ; +#1310=CARTESIAN_POINT('Control Point',(1.46135276871,-6.80390140682,-9.30389465826)) ; +#1311=CARTESIAN_POINT('Control Point',(1.38209084822,-7.00229313499,-9.50228479367)) ; +#1312=CARTESIAN_POINT('Control Point',(1.24254361508,-7.18462387437,-9.68463244784)) ; +#1313=CARTESIAN_POINT('Control Point',(1.15662240902,-7.26921826151,-9.76921898666)) ; +#1314=CARTESIAN_POINT('Control Point',(0.987345401215,-7.39073963531,-9.89073916732)) ; +#1315=CARTESIAN_POINT('Control Point',(0.774983165596,-7.46765962756,-9.96765992959)) ; +#1316=CARTESIAN_POINT('Control Point',(0.685696192877,-7.48922399455,-9.98922399452)) ; +#1317=CARTESIAN_POINT('Control Point',(0.592848286933,-7.5,-10.)) ; +#1318=CARTESIAN_POINT('Control Point',(0.5,-7.5,-10.)) ; +#1319=CARTESIAN_POINT('Vertex',(1.5,-6.5,-9.)) ; +#1322=CARTESIAN_POINT('Line Origine',(1.5,0.,-9.)) ; +#1334=CARTESIAN_POINT('Axis2P3D Location',(0.5,-6.5,0.)) ; +#1339=CARTESIAN_POINT('Line Origine',(1.5,-6.5,0.)) ; +#1351=CARTESIAN_POINT('Axis2P3D Location',(-23.679356624,2.220446E-016,0.)) ; +#1356=CARTESIAN_POINT('Axis2P3D Location',(0.5,2.220446E-016,0.)) ; +#1360=CARTESIAN_POINT('Vertex',(0.5,2.220446E-016,5.)) ; +#1362=CARTESIAN_POINT('Vertex',(0.5,8.34347776911E-016,-5.)) ; +#1365=CARTESIAN_POINT('Line Origine',(-23.6793566234,2.220446E-016,5.)) ; +#1370=CARTESIAN_POINT('Line Origine',(-23.6793566234,8.34347776911E-016,-5.)) ; +#1382=CARTESIAN_POINT('Axis2P3D Location',(-23.679356624,2.220446E-016,0.)) ; +#1387=CARTESIAN_POINT('Axis2P3D Location',(0.5,2.220446E-016,0.)) ; +#1399=CARTESIAN_POINT('Axis2P3D Location',(1.5,0.,0.)) ; +#1410=CARTESIAN_POINT('Axis2P3D Location',(1.5,4.7878367937E-015,-4.55191440096E-015)) ; +#1414=CARTESIAN_POINT('Vertex',(1.5,6.48547187913E-008,6.)) ; +#1416=CARTESIAN_POINT('Vertex',(1.5,-2.50929248776E-008,-6.)) ; +#1419=CARTESIAN_POINT('Axis2P3D Location',(1.5,-9.32587340685E-015,8.43769498715E-015)) ; +#1429=CARTESIAN_POINT('Axis2P3D Location',(0.5,0.,-4.4408920985E-016)) ; +#1434=CARTESIAN_POINT('Axis2P3D Location',(0.5,0.,6.)) ; +#1439=CARTESIAN_POINT('Axis2P3D Location',(0.5,7.66053886991E-015,-6.)) ; +#1451=CARTESIAN_POINT('Axis2P3D Location',(0.5,-1.11022302463E-015,-4.4408920985E-016)) ; +#1473=CARTESIAN_POINT('NONE',(0.,0.,0.)) ; +#1474=CARTESIAN_POINT('NONE',(252.527291545,100.352946986,18.9365794127)) ; +#1486=CARTESIAN_POINT('NONE',(0.,0.,0.)) ; +#1487=CARTESIAN_POINT('NONE',(-97.5272915445,56.0634205873,98.8529469863)) ; +#1501=CARTESIAN_POINT('NONE',(0.,0.,0.)) ; +#1502=CARTESIAN_POINT('NONE',(-120.027291545,43.0730395305,98.8529469863)) ; +#64=DIRECTION('Axis2P3D Direction',(1.,1.224606E-016,-0.)) ; +#65=DIRECTION('Axis2P3D XDirection',(0.,0.,1.)) ; +#69=DIRECTION('Vector Direction',(1.,1.22460619423E-016,0.)) ; +#97=DIRECTION('Vector Direction',(1.,1.22460619423E-016,0.)) ; +#128=DIRECTION('Axis2P3D Direction',(1.,1.224606E-016,-0.)) ; +#129=DIRECTION('Axis2P3D XDirection',(1.49970981812E-032,-1.22464679915E-016,-1.)) ; +#133=DIRECTION('Axis2P3D Direction',(1.,1.224606E-016,-0.)) ; +#138=DIRECTION('Axis2P3D Direction',(1.,1.224606E-016,-0.)) ; +#150=DIRECTION('Axis2P3D Direction',(1.,0.,0.)) ; +#151=DIRECTION('Axis2P3D XDirection',(0.,0.,-1.)) ; +#155=DIRECTION('Vector Direction',(0.,-1.,0.)) ; +#164=DIRECTION('Vector Direction',(0.,0.,1.)) ; +#171=DIRECTION('Vector Direction',(0.,-1.,0.)) ; +#178=DIRECTION('Vector Direction',(0.,0.,1.)) ; +#302=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#303=DIRECTION('Axis2P3D XDirection',(0.,0.,1.)) ; +#307=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#316=DIRECTION('Vector Direction',(0.,0.,1.)) ; +#323=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#330=DIRECTION('Vector Direction',(0.,0.,1.)) ; +#454=DIRECTION('Axis2P3D Direction',(0.,0.,-1.)) ; +#455=DIRECTION('Axis2P3D XDirection',(-1.,0.,0.)) ; +#459=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#464=DIRECTION('Vector Direction',(1.,0.,0.)) ; +#471=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#478=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#492=DIRECTION('Axis2P3D Direction',(0.,-1.,0.)) ; +#493=DIRECTION('Axis2P3D XDirection',(0.,0.,-1.)) ; +#497=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#509=DIRECTION('Axis2P3D Direction',(0.,0.,1.)) ; +#510=DIRECTION('Axis2P3D XDirection',(1.,0.,0.)) ; +#514=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#521=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#528=DIRECTION('Vector Direction',(1.,0.,0.)) ; +#542=DIRECTION('Axis2P3D Direction',(0.,1.,0.)) ; +#543=DIRECTION('Axis2P3D XDirection',(0.,0.,1.)) ; +#547=DIRECTION('Vector Direction',(0.,0.,1.)) ; +#613=DIRECTION('Axis2P3D Direction',(1.,3.06151588734E-017,-5.30270106505E-017)) ; +#614=DIRECTION('Axis2P3D XDirection',(0.,-0.866025403784,-0.5)) ; +#618=DIRECTION('Vector Direction',(1.,3.06151548557E-017,-5.3027093827E-017)) ; +#623=DIRECTION('Vector Direction',(1.,3.06151548557E-017,-5.3027093827E-017)) ; +#635=DIRECTION('Axis2P3D Direction',(1.,3.06151588734E-017,-5.30270106505E-017)) ; +#636=DIRECTION('Axis2P3D XDirection',(-7.49855126393E-033,0.866025403784,0.5)) ; +#647=DIRECTION('Axis2P3D Direction',(1.,3.06151588734E-017,5.30270106505E-017)) ; +#648=DIRECTION('Axis2P3D XDirection',(0.,0.866025403784,-0.5)) ; +#652=DIRECTION('Vector Direction',(1.,3.06151548557E-017,5.3027093827E-017)) ; +#657=DIRECTION('Vector Direction',(1.,3.06151548557E-017,5.3027093827E-017)) ; +#669=DIRECTION('Axis2P3D Direction',(1.,3.06151588734E-017,5.30270106505E-017)) ; +#670=DIRECTION('Axis2P3D XDirection',(-7.49855126393E-033,-0.866025403784,0.5)) ; +#681=DIRECTION('Axis2P3D Direction',(0.,-1.,0.)) ; +#682=DIRECTION('Axis2P3D XDirection',(0.,0.,-1.)) ; +#686=DIRECTION('Vector Direction',(0.,0.,1.)) ; +#752=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#753=DIRECTION('Axis2P3D XDirection',(0.,0.,1.)) ; +#764=DIRECTION('Axis2P3D Direction',(0.,1.,0.)) ; +#765=DIRECTION('Axis2P3D XDirection',(0.,0.,-1.)) ; +#769=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#774=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#786=DIRECTION('Axis2P3D Direction',(0.,1.,0.)) ; +#787=DIRECTION('Axis2P3D XDirection',(-1.22464679915E-016,0.,1.)) ; +#809=DIRECTION('NONE',(1.,0.,0.)) ; +#810=DIRECTION('NONE',(0.,0.,1.)) ; +#811=DIRECTION('NONE',(-2.220446E-016,2.220446E-016,-1.)) ; +#812=DIRECTION('NONE',(-2.220446E-016,-1.,-2.220446E-016)) ; +#833=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#834=DIRECTION('Axis2P3D XDirection',(0.,0.,1.)) ; +#838=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#847=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#856=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#865=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#875=DIRECTION('Axis2P3D Direction',(1.,0.,0.)) ; +#876=DIRECTION('Axis2P3D XDirection',(0.,-1.,1.22464679915E-016)) ; +#880=DIRECTION('Vector Direction',(1.,0.,0.)) ; +#887=DIRECTION('Axis2P3D Direction',(1.,0.,0.)) ; +#894=DIRECTION('Vector Direction',(1.,0.,0.)) ; +#906=DIRECTION('Axis2P3D Direction',(1.,0.,0.)) ; +#907=DIRECTION('Axis2P3D XDirection',(0.,1.,0.)) ; +#911=DIRECTION('Axis2P3D Direction',(1.,0.,0.)) ; +#923=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#924=DIRECTION('Axis2P3D XDirection',(0.,0.,1.)) ; +#933=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#934=DIRECTION('Axis2P3D XDirection',(0.,1.,0.)) ; +#938=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#945=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#952=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#964=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#965=DIRECTION('Axis2P3D XDirection',(0.,-1.,-5.66553889765E-016)) ; +#969=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#981=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#982=DIRECTION('Axis2P3D XDirection',(0.,0.,1.)) ; +#986=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#995=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#1005=DIRECTION('Axis2P3D Direction',(-1.,-0.,0.)) ; +#1006=DIRECTION('Axis2P3D XDirection',(0.,-0.916336428703,-0.400409227456)) ; +#1010=DIRECTION('Axis2P3D Direction',(0.,-4.99326358039E-010,1.)) ; +#1015=DIRECTION('Axis2P3D Direction',(-0.,1.74906738537E-008,-1.)) ; +#1027=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#1028=DIRECTION('Axis2P3D XDirection',(0.,0.909870182947,0.414893058733)) ; +#1050=DIRECTION('NONE',(1.,0.,0.)) ; +#1051=DIRECTION('NONE',(0.,0.,1.)) ; +#1052=DIRECTION('NONE',(0.,1.,1.224606E-016)) ; +#1053=DIRECTION('NONE',(-1.,0.,0.)) ; +#1066=DIRECTION('Axis2P3D Direction',(1.,0.,0.)) ; +#1067=DIRECTION('Axis2P3D XDirection',(0.,0.,-1.)) ; +#1071=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#1080=DIRECTION('Vector Direction',(0.,0.,-1.)) ; +#1087=DIRECTION('Vector Direction',(0.,-1.,0.)) ; +#1094=DIRECTION('Vector Direction',(0.,0.,1.)) ; +#1105=DIRECTION('Axis2P3D Direction',(1.,0.,0.)) ; +#1114=DIRECTION('Axis2P3D Direction',(1.,0.,0.)) ; +#1124=DIRECTION('Axis2P3D Direction',(0.,0.,-1.)) ; +#1125=DIRECTION('Axis2P3D XDirection',(-1.,0.,0.)) ; +#1129=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#1136=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#1143=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#1155=DIRECTION('Axis2P3D Direction',(0.,-1.,0.)) ; +#1156=DIRECTION('Axis2P3D XDirection',(0.,0.,-1.)) ; +#1160=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#1167=DIRECTION('Vector Direction',(0.,0.,-1.)) ; +#1179=DIRECTION('Axis2P3D Direction',(0.,0.,1.)) ; +#1180=DIRECTION('Axis2P3D XDirection',(1.,0.,0.)) ; +#1184=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#1191=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#1203=DIRECTION('Axis2P3D Direction',(0.,1.,0.)) ; +#1204=DIRECTION('Axis2P3D XDirection',(0.,0.,1.)) ; +#1208=DIRECTION('Vector Direction',(0.,0.,1.)) ; +#1220=DIRECTION('Axis2P3D Direction',(-0.,1.,0.)) ; +#1221=DIRECTION('Axis2P3D XDirection',(-1.83697019872E-016,-0.,1.)) ; +#1257=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#1269=DIRECTION('Axis2P3D Direction',(0.,0.,1.)) ; +#1270=DIRECTION('Axis2P3D XDirection',(1.,0.,0.)) ; +#1290=DIRECTION('Vector Direction',(0.,0.,1.)) ; +#1302=DIRECTION('Axis2P3D Direction',(-0.,1.,0.)) ; +#1303=DIRECTION('Axis2P3D XDirection',(1.,0.,0.)) ; +#1323=DIRECTION('Vector Direction',(0.,1.,0.)) ; +#1335=DIRECTION('Axis2P3D Direction',(0.,0.,-1.)) ; +#1336=DIRECTION('Axis2P3D XDirection',(1.,0.,0.)) ; +#1340=DIRECTION('Vector Direction',(0.,0.,-1.)) ; +#1352=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#1353=DIRECTION('Axis2P3D XDirection',(0.,0.,1.)) ; +#1357=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#1366=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#1371=DIRECTION('Vector Direction',(-1.,0.,0.)) ; +#1383=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#1384=DIRECTION('Axis2P3D XDirection',(0.,1.22464679915E-016,-1.)) ; +#1388=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#1400=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#1401=DIRECTION('Axis2P3D XDirection',(0.,0.,1.)) ; +#1411=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#1420=DIRECTION('Axis2P3D Direction',(-1.,0.,0.)) ; +#1430=DIRECTION('Axis2P3D Direction',(-1.,-0.,0.)) ; +#1431=DIRECTION('Axis2P3D XDirection',(0.,-0.327595417415,0.944818100212)) ; +#1435=DIRECTION('Axis2P3D Direction',(0.,-1.,0.)) ; +#1440=DIRECTION('Axis2P3D Direction',(0.,1.,1.27675647832E-015)) ; +#1452=DIRECTION('Axis2P3D Direction',(-1.,0.,-0.)) ; +#1453=DIRECTION('Axis2P3D XDirection',(0.,0.371212471839,-0.928547952855)) ; +#1475=DIRECTION('NONE',(1.,0.,0.)) ; +#1476=DIRECTION('NONE',(0.,0.,1.)) ; +#1477=DIRECTION('NONE',(0.,1.,1.224606E-016)) ; +#1478=DIRECTION('NONE',(-1.,0.,0.)) ; +#1488=DIRECTION('NONE',(1.,0.,0.)) ; +#1489=DIRECTION('NONE',(0.,0.,1.)) ; +#1490=DIRECTION('NONE',(1.,-2.220446E-016,-4.93038065763E-032)) ; +#1491=DIRECTION('NONE',(2.220446E-016,1.,0.)) ; +#1503=DIRECTION('NONE',(1.,0.,0.)) ; +#1504=DIRECTION('NONE',(0.,0.,1.)) ; +#1505=DIRECTION('NONE',(1.,-2.220446E-016,-4.93038065763E-032)) ; +#1506=DIRECTION('NONE',(2.220446E-016,1.,0.)) ; +#66=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#63,#64,#65) ; +#130=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#127,#128,#129) ; +#134=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#132,#133,$) ; +#139=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#137,#138,$) ; +#152=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#149,#150,#151) ; +#304=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#301,#302,#303) ; +#456=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#453,#454,#455) ; +#494=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#491,#492,#493) ; +#511=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#508,#509,#510) ; +#544=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#541,#542,#543) ; +#615=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#612,#613,#614) ; +#637=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#634,#635,#636) ; +#649=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#646,#647,#648) ; +#671=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#668,#669,#670) ; +#683=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#680,#681,#682) ; +#754=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#751,#752,#753) ; +#766=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#763,#764,#765) ; +#788=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#785,#786,#787) ; +#805=AXIS2_PLACEMENT_3D(' ',#808,#812,#811) ; +#806=AXIS2_PLACEMENT_3D(' ',#807,#810,#809) ; +#835=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#832,#833,#834) ; +#839=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#837,#838,$) ; +#848=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#846,#847,$) ; +#857=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#855,#856,$) ; +#866=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#864,#865,$) ; +#877=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#874,#875,#876) ; +#888=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#886,#887,$) ; +#908=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#905,#906,#907) ; +#912=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#910,#911,$) ; +#925=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#922,#923,#924) ; +#935=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#932,#933,#934) ; +#953=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#951,#952,$) ; +#966=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#963,#964,#965) ; +#970=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#968,#969,$) ; +#983=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#980,#981,#982) ; +#987=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#985,#986,$) ; +#996=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#994,#995,$) ; +#1007=AXIS2_PLACEMENT_3D('Torus Axis2P3D',#1004,#1005,#1006) ; +#1011=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#1009,#1010,$) ; +#1016=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#1014,#1015,$) ; +#1029=AXIS2_PLACEMENT_3D('Torus Axis2P3D',#1026,#1027,#1028) ; +#1046=AXIS2_PLACEMENT_3D(' ',#1049,#1053,#1052) ; +#1047=AXIS2_PLACEMENT_3D(' ',#1048,#1051,#1050) ; +#1068=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#1065,#1066,#1067) ; +#1106=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#1104,#1105,$) ; +#1115=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#1113,#1114,$) ; +#1126=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#1123,#1124,#1125) ; +#1157=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#1154,#1155,#1156) ; +#1181=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#1178,#1179,#1180) ; +#1205=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#1202,#1203,#1204) ; +#1222=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#1219,#1220,#1221) ; +#1271=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#1268,#1269,#1270) ; +#1304=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#1301,#1302,#1303) ; +#1337=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#1334,#1335,#1336) ; +#1354=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#1351,#1352,#1353) ; +#1358=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#1356,#1357,$) ; +#1385=AXIS2_PLACEMENT_3D('Cylinder Axis2P3D',#1382,#1383,#1384) ; +#1389=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#1387,#1388,$) ; +#1402=AXIS2_PLACEMENT_3D('Plane Axis2P3D',#1399,#1400,#1401) ; +#1412=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#1410,#1411,$) ; +#1421=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#1419,#1420,$) ; +#1432=AXIS2_PLACEMENT_3D('Torus Axis2P3D',#1429,#1430,#1431) ; +#1436=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#1434,#1435,$) ; +#1441=AXIS2_PLACEMENT_3D('Circle Axis2P3D',#1439,#1440,$) ; +#1454=AXIS2_PLACEMENT_3D('Torus Axis2P3D',#1451,#1452,#1453) ; +#1471=AXIS2_PLACEMENT_3D(' ',#1474,#1478,#1477) ; +#1472=AXIS2_PLACEMENT_3D(' ',#1473,#1476,#1475) ; +#1484=AXIS2_PLACEMENT_3D(' ',#1487,#1491,#1490) ; +#1485=AXIS2_PLACEMENT_3D(' ',#1486,#1489,#1488) ; +#1499=AXIS2_PLACEMENT_3D(' ',#1502,#1506,#1505) ; +#1500=AXIS2_PLACEMENT_3D(' ',#1501,#1504,#1503) ; +#45=PRODUCT_DEFINITION_SHAPE(' ',' ',#17) ; +#61=PRODUCT_DEFINITION_SHAPE(' ',' ',#58) ; +#801=PRODUCT_DEFINITION_SHAPE(' ',' ',#800) ; +#820=PRODUCT_DEFINITION_SHAPE(' ',' ',#819) ; +#830=PRODUCT_DEFINITION_SHAPE(' ',' ',#827) ; +#1042=PRODUCT_DEFINITION_SHAPE(' ',' ',#1041) ; +#1063=PRODUCT_DEFINITION_SHAPE(' ',' ',#1060) ; +#1467=PRODUCT_DEFINITION_SHAPE(' ',' ',#1466) ; +#1480=PRODUCT_DEFINITION_SHAPE(' ',' ',#1479) ; +#1495=PRODUCT_DEFINITION_SHAPE(' ',' ',#1494) ; +#34=APPROVAL_PERSON_ORGANIZATION(#28,#24,#22) ; +#28=PERSON_AND_ORGANIZATION(#25,#26) ; +#25=PERSON(' ',' ',' ',$,$,$) ; +#26=ORGANIZATION(' ',' ',' ') ; +#24=APPROVAL(#23,' ') ; +#23=APPROVAL_STATUS('not_yet_approved') ; +#22=APPROVAL_ROLE('APPROVER') ; +#13=DATE_AND_TIME(#11,#12) ; +#12=LOCAL_TIME(12,25,11.,#10) ; +#10=COORDINATED_UNIVERSAL_TIME_OFFSET(0,0,.AHEAD.) ; +#121=ORIENTED_EDGE('',*,*,#76,.F.) ; +#122=ORIENTED_EDGE('',*,*,#95,.F.) ; +#123=ORIENTED_EDGE('',*,*,#102,.F.) ; +#124=ORIENTED_EDGE('',*,*,#119,.F.) ; +#143=ORIENTED_EDGE('',*,*,#76,.T.) ; +#144=ORIENTED_EDGE('',*,*,#136,.F.) ; +#145=ORIENTED_EDGE('',*,*,#102,.T.) ; +#146=ORIENTED_EDGE('',*,*,#141,.F.) ; +#183=ORIENTED_EDGE('',*,*,#162,.T.) ; +#184=ORIENTED_EDGE('',*,*,#169,.F.) ; +#185=ORIENTED_EDGE('',*,*,#176,.F.) ; +#186=ORIENTED_EDGE('',*,*,#181,.T.) ; +#239=ORIENTED_EDGE('',*,*,#214,.T.) ; +#240=ORIENTED_EDGE('',*,*,#237,.T.) ; +#293=ORIENTED_EDGE('',*,*,#268,.T.) ; +#294=ORIENTED_EDGE('',*,*,#291,.T.) ; +#297=ORIENTED_EDGE('',*,*,#95,.T.) ; +#298=ORIENTED_EDGE('',*,*,#141,.T.) ; +#335=ORIENTED_EDGE('',*,*,#314,.T.) ; +#336=ORIENTED_EDGE('',*,*,#321,.F.) ; +#337=ORIENTED_EDGE('',*,*,#328,.F.) ; +#338=ORIENTED_EDGE('',*,*,#333,.T.) ; +#391=ORIENTED_EDGE('',*,*,#366,.T.) ; +#392=ORIENTED_EDGE('',*,*,#389,.T.) ; +#445=ORIENTED_EDGE('',*,*,#420,.T.) ; +#446=ORIENTED_EDGE('',*,*,#443,.T.) ; +#449=ORIENTED_EDGE('',*,*,#119,.T.) ; +#450=ORIENTED_EDGE('',*,*,#136,.T.) ; +#483=ORIENTED_EDGE('',*,*,#314,.F.) ; +#484=ORIENTED_EDGE('',*,*,#462,.F.) ; +#485=ORIENTED_EDGE('',*,*,#162,.F.) ; +#486=ORIENTED_EDGE('',*,*,#469,.F.) ; +#487=ORIENTED_EDGE('',*,*,#476,.F.) ; +#488=ORIENTED_EDGE('',*,*,#481,.F.) ; +#502=ORIENTED_EDGE('',*,*,#462,.T.) ; +#503=ORIENTED_EDGE('',*,*,#333,.F.) ; +#504=ORIENTED_EDGE('',*,*,#500,.F.) ; +#505=ORIENTED_EDGE('',*,*,#169,.T.) ; +#533=ORIENTED_EDGE('',*,*,#500,.T.) ; +#534=ORIENTED_EDGE('',*,*,#328,.T.) ; +#535=ORIENTED_EDGE('',*,*,#519,.T.) ; +#536=ORIENTED_EDGE('',*,*,#526,.T.) ; +#537=ORIENTED_EDGE('',*,*,#531,.T.) ; +#538=ORIENTED_EDGE('',*,*,#176,.T.) ; +#552=ORIENTED_EDGE('',*,*,#469,.T.) ; +#553=ORIENTED_EDGE('',*,*,#181,.F.) ; +#554=ORIENTED_EDGE('',*,*,#531,.F.) ; +#555=ORIENTED_EDGE('',*,*,#550,.T.) ; +#608=ORIENTED_EDGE('',*,*,#583,.T.) ; +#609=ORIENTED_EDGE('',*,*,#606,.T.) ; +#628=ORIENTED_EDGE('',*,*,#621,.F.) ; +#629=ORIENTED_EDGE('',*,*,#214,.F.) ; +#630=ORIENTED_EDGE('',*,*,#626,.F.) ; +#631=ORIENTED_EDGE('',*,*,#366,.F.) ; +#640=ORIENTED_EDGE('',*,*,#621,.T.) ; +#641=ORIENTED_EDGE('',*,*,#389,.F.) ; +#642=ORIENTED_EDGE('',*,*,#626,.T.) ; +#643=ORIENTED_EDGE('',*,*,#237,.F.) ; +#662=ORIENTED_EDGE('',*,*,#655,.F.) ; +#663=ORIENTED_EDGE('',*,*,#268,.F.) ; +#664=ORIENTED_EDGE('',*,*,#660,.F.) ; +#665=ORIENTED_EDGE('',*,*,#420,.F.) ; +#674=ORIENTED_EDGE('',*,*,#655,.T.) ; +#675=ORIENTED_EDGE('',*,*,#443,.F.) ; +#676=ORIENTED_EDGE('',*,*,#660,.T.) ; +#677=ORIENTED_EDGE('',*,*,#291,.F.) ; +#691=ORIENTED_EDGE('',*,*,#481,.T.) ; +#692=ORIENTED_EDGE('',*,*,#689,.F.) ; +#693=ORIENTED_EDGE('',*,*,#519,.F.) ; +#694=ORIENTED_EDGE('',*,*,#321,.T.) ; +#747=ORIENTED_EDGE('',*,*,#722,.T.) ; +#748=ORIENTED_EDGE('',*,*,#745,.T.) ; +#757=ORIENTED_EDGE('',*,*,#476,.T.) ; +#758=ORIENTED_EDGE('',*,*,#550,.F.) ; +#759=ORIENTED_EDGE('',*,*,#526,.F.) ; +#760=ORIENTED_EDGE('',*,*,#689,.T.) ; +#779=ORIENTED_EDGE('',*,*,#772,.F.) ; +#780=ORIENTED_EDGE('',*,*,#583,.F.) ; +#781=ORIENTED_EDGE('',*,*,#777,.F.) ; +#782=ORIENTED_EDGE('',*,*,#722,.F.) ; +#791=ORIENTED_EDGE('',*,*,#772,.T.) ; +#792=ORIENTED_EDGE('',*,*,#745,.F.) ; +#793=ORIENTED_EDGE('',*,*,#777,.T.) ; +#794=ORIENTED_EDGE('',*,*,#606,.F.) ; +#852=ORIENTED_EDGE('',*,*,#845,.F.) ; +#853=ORIENTED_EDGE('',*,*,#850,.F.) ; +#870=ORIENTED_EDGE('',*,*,#863,.T.) ; +#871=ORIENTED_EDGE('',*,*,#868,.T.) ; +#899=ORIENTED_EDGE('',*,*,#885,.T.) ; +#900=ORIENTED_EDGE('',*,*,#892,.T.) ; +#901=ORIENTED_EDGE('',*,*,#897,.T.) ; +#902=ORIENTED_EDGE('',*,*,#863,.F.) ; +#916=ORIENTED_EDGE('',*,*,#885,.F.) ; +#917=ORIENTED_EDGE('',*,*,#868,.F.) ; +#918=ORIENTED_EDGE('',*,*,#897,.F.) ; +#919=ORIENTED_EDGE('',*,*,#914,.T.) ; +#928=ORIENTED_EDGE('',*,*,#892,.F.) ; +#929=ORIENTED_EDGE('',*,*,#914,.F.) ; +#957=ORIENTED_EDGE('',*,*,#943,.F.) ; +#958=ORIENTED_EDGE('',*,*,#845,.T.) ; +#959=ORIENTED_EDGE('',*,*,#950,.F.) ; +#960=ORIENTED_EDGE('',*,*,#955,.T.) ; +#974=ORIENTED_EDGE('',*,*,#950,.T.) ; +#975=ORIENTED_EDGE('',*,*,#850,.T.) ; +#976=ORIENTED_EDGE('',*,*,#943,.T.) ; +#977=ORIENTED_EDGE('',*,*,#972,.T.) ; +#1000=ORIENTED_EDGE('',*,*,#993,.F.) ; +#1001=ORIENTED_EDGE('',*,*,#998,.F.) ; +#1020=ORIENTED_EDGE('',*,*,#1013,.T.) ; +#1021=ORIENTED_EDGE('',*,*,#993,.T.) ; +#1022=ORIENTED_EDGE('',*,*,#1018,.F.) ; +#1023=ORIENTED_EDGE('',*,*,#972,.F.) ; +#1032=ORIENTED_EDGE('',*,*,#1018,.T.) ; +#1033=ORIENTED_EDGE('',*,*,#998,.T.) ; +#1034=ORIENTED_EDGE('',*,*,#1013,.F.) ; +#1035=ORIENTED_EDGE('',*,*,#955,.F.) ; +#1099=ORIENTED_EDGE('',*,*,#1078,.F.) ; +#1100=ORIENTED_EDGE('',*,*,#1085,.F.) ; +#1101=ORIENTED_EDGE('',*,*,#1092,.F.) ; +#1102=ORIENTED_EDGE('',*,*,#1097,.F.) ; +#1119=ORIENTED_EDGE('',*,*,#1112,.T.) ; +#1120=ORIENTED_EDGE('',*,*,#1117,.T.) ; +#1148=ORIENTED_EDGE('',*,*,#1134,.T.) ; +#1149=ORIENTED_EDGE('',*,*,#1078,.T.) ; +#1150=ORIENTED_EDGE('',*,*,#1141,.F.) ; +#1151=ORIENTED_EDGE('',*,*,#1146,.T.) ; +#1172=ORIENTED_EDGE('',*,*,#1165,.T.) ; +#1173=ORIENTED_EDGE('',*,*,#1085,.T.) ; +#1174=ORIENTED_EDGE('',*,*,#1134,.F.) ; +#1175=ORIENTED_EDGE('',*,*,#1170,.T.) ; +#1196=ORIENTED_EDGE('',*,*,#1189,.T.) ; +#1197=ORIENTED_EDGE('',*,*,#1092,.T.) ; +#1198=ORIENTED_EDGE('',*,*,#1165,.F.) ; +#1199=ORIENTED_EDGE('',*,*,#1194,.T.) ; +#1213=ORIENTED_EDGE('',*,*,#1141,.T.) ; +#1214=ORIENTED_EDGE('',*,*,#1097,.T.) ; +#1215=ORIENTED_EDGE('',*,*,#1189,.F.) ; +#1216=ORIENTED_EDGE('',*,*,#1211,.T.) ; +#1262=ORIENTED_EDGE('',*,*,#1239,.T.) ; +#1263=ORIENTED_EDGE('',*,*,#1194,.F.) ; +#1264=ORIENTED_EDGE('',*,*,#1255,.T.) ; +#1265=ORIENTED_EDGE('',*,*,#1260,.T.) ; +#1295=ORIENTED_EDGE('',*,*,#1288,.T.) ; +#1296=ORIENTED_EDGE('',*,*,#1211,.F.) ; +#1297=ORIENTED_EDGE('',*,*,#1239,.F.) ; +#1298=ORIENTED_EDGE('',*,*,#1293,.T.) ; +#1328=ORIENTED_EDGE('',*,*,#1321,.T.) ; +#1329=ORIENTED_EDGE('',*,*,#1146,.F.) ; +#1330=ORIENTED_EDGE('',*,*,#1288,.F.) ; +#1331=ORIENTED_EDGE('',*,*,#1326,.T.) ; +#1345=ORIENTED_EDGE('',*,*,#1255,.F.) ; +#1346=ORIENTED_EDGE('',*,*,#1170,.F.) ; +#1347=ORIENTED_EDGE('',*,*,#1321,.F.) ; +#1348=ORIENTED_EDGE('',*,*,#1343,.T.) ; +#1376=ORIENTED_EDGE('',*,*,#1364,.F.) ; +#1377=ORIENTED_EDGE('',*,*,#1369,.F.) ; +#1378=ORIENTED_EDGE('',*,*,#1112,.F.) ; +#1379=ORIENTED_EDGE('',*,*,#1374,.F.) ; +#1393=ORIENTED_EDGE('',*,*,#1391,.F.) ; +#1394=ORIENTED_EDGE('',*,*,#1374,.T.) ; +#1395=ORIENTED_EDGE('',*,*,#1117,.F.) ; +#1396=ORIENTED_EDGE('',*,*,#1369,.T.) ; +#1405=ORIENTED_EDGE('',*,*,#1260,.F.) ; +#1406=ORIENTED_EDGE('',*,*,#1343,.F.) ; +#1407=ORIENTED_EDGE('',*,*,#1326,.F.) ; +#1408=ORIENTED_EDGE('',*,*,#1293,.F.) ; +#1425=ORIENTED_EDGE('',*,*,#1418,.T.) ; +#1426=ORIENTED_EDGE('',*,*,#1423,.T.) ; +#1445=ORIENTED_EDGE('',*,*,#1438,.T.) ; +#1446=ORIENTED_EDGE('',*,*,#1364,.T.) ; +#1447=ORIENTED_EDGE('',*,*,#1443,.F.) ; +#1448=ORIENTED_EDGE('',*,*,#1418,.F.) ; +#1457=ORIENTED_EDGE('',*,*,#1443,.T.) ; +#1458=ORIENTED_EDGE('',*,*,#1391,.T.) ; +#1459=ORIENTED_EDGE('',*,*,#1438,.F.) ; +#1460=ORIENTED_EDGE('',*,*,#1423,.F.) ; +#241=FACE_BOUND('',#238,.T.) ; +#295=FACE_BOUND('',#292,.T.) ; +#299=FACE_BOUND('',#296,.T.) ; +#393=FACE_BOUND('',#390,.T.) ; +#447=FACE_BOUND('',#444,.T.) ; +#451=FACE_BOUND('',#448,.T.) ; +#610=FACE_BOUND('',#607,.T.) ; +#749=FACE_BOUND('',#746,.T.) ; +#872=FACE_BOUND('',#869,.T.) ; +#1121=FACE_BOUND('',#1118,.T.) ; +#1427=FACE_BOUND('',#1424,.T.) ; +#62=CLOSED_SHELL('Closed Shell',(#126,#148,#300,#452,#490,#507,#540,#611,#633,#645,#667,#679,#750,#762,#784,#796)) ; +#831=CLOSED_SHELL('Closed Shell',(#873,#904,#921,#931,#962,#979,#1003,#1025,#1037)) ; +#1064=CLOSED_SHELL('Closed Shell',(#1122,#1153,#1177,#1201,#1218,#1267,#1300,#1333,#1350,#1381,#1398,#1428,#1450,#1462)) ; +#804=ITEM_DEFINED_TRANSFORMATION(' ',' ',#806,#805) ; +#1045=ITEM_DEFINED_TRANSFORMATION(' ',' ',#1047,#1046) ; +#1470=ITEM_DEFINED_TRANSFORMATION(' ',' ',#1472,#1471) ; +#1483=ITEM_DEFINED_TRANSFORMATION(' ',' ',#1485,#1484) ; +#1498=ITEM_DEFINED_TRANSFORMATION(' ',' ',#1500,#1499) ; +#70=VECTOR('Line Direction',#69,1.) ; +#98=VECTOR('Line Direction',#97,1.) ; +#156=VECTOR('Line Direction',#155,1.) ; +#165=VECTOR('Line Direction',#164,1.) ; +#172=VECTOR('Line Direction',#171,1.) ; +#179=VECTOR('Line Direction',#178,1.) ; +#308=VECTOR('Line Direction',#307,1.) ; +#317=VECTOR('Line Direction',#316,1.) ; +#324=VECTOR('Line Direction',#323,1.) ; +#331=VECTOR('Line Direction',#330,1.) ; +#460=VECTOR('Line Direction',#459,1.) ; +#465=VECTOR('Line Direction',#464,1.) ; +#472=VECTOR('Line Direction',#471,1.) ; +#479=VECTOR('Line Direction',#478,1.) ; +#498=VECTOR('Line Direction',#497,1.) ; +#515=VECTOR('Line Direction',#514,1.) ; +#522=VECTOR('Line Direction',#521,1.) ; +#529=VECTOR('Line Direction',#528,1.) ; +#548=VECTOR('Line Direction',#547,1.) ; +#619=VECTOR('Line Direction',#618,1.) ; +#624=VECTOR('Line Direction',#623,1.) ; +#653=VECTOR('Line Direction',#652,1.) ; +#658=VECTOR('Line Direction',#657,1.) ; +#687=VECTOR('Line Direction',#686,1.) ; +#770=VECTOR('Line Direction',#769,1.) ; +#775=VECTOR('Line Direction',#774,1.) ; +#881=VECTOR('Line Direction',#880,1.) ; +#895=VECTOR('Line Direction',#894,1.) ; +#939=VECTOR('Line Direction',#938,1.) ; +#946=VECTOR('Line Direction',#945,1.) ; +#1072=VECTOR('Line Direction',#1071,1.) ; +#1081=VECTOR('Line Direction',#1080,1.) ; +#1088=VECTOR('Line Direction',#1087,1.) ; +#1095=VECTOR('Line Direction',#1094,1.) ; +#1130=VECTOR('Line Direction',#1129,1.) ; +#1137=VECTOR('Line Direction',#1136,1.) ; +#1144=VECTOR('Line Direction',#1143,1.) ; +#1161=VECTOR('Line Direction',#1160,1.) ; +#1168=VECTOR('Line Direction',#1167,1.) ; +#1185=VECTOR('Line Direction',#1184,1.) ; +#1192=VECTOR('Line Direction',#1191,1.) ; +#1209=VECTOR('Line Direction',#1208,1.) ; +#1258=VECTOR('Line Direction',#1257,1.) ; +#1291=VECTOR('Line Direction',#1290,1.) ; +#1324=VECTOR('Line Direction',#1323,1.) ; +#1341=VECTOR('Line Direction',#1340,1.) ; +#1367=VECTOR('Line Direction',#1366,1.) ; +#1372=VECTOR('Line Direction',#1371,1.) ; +#798=ADVANCED_BREP_SHAPE_REPRESENTATION('NONE',(#797),#53) ; +#1039=ADVANCED_BREP_SHAPE_REPRESENTATION('NONE',(#1038),#822) ; +#1464=ADVANCED_BREP_SHAPE_REPRESENTATION('NONE',(#1463),#1055) ; +#44=SHAPE_REPRESENTATION(' ',(#805,#1484,#1499),#51) ; +#54=SHAPE_REPRESENTATION(' ',(#806),#53) ; +#815=SHAPE_REPRESENTATION(' ',(#1046,#1471,#1485,#1500),#814) ; +#823=SHAPE_REPRESENTATION(' ',(#1047),#822) ; +#1056=SHAPE_REPRESENTATION(' ',(#1472),#1055) ; +#126=ADVANCED_FACE('52D',(#125),#67,.F.) ; +#148=ADVANCED_FACE('52D',(#147),#131,.F.) ; +#300=ADVANCED_FACE('52D',(#187,#241,#295,#299),#153,.T.) ; +#452=ADVANCED_FACE('52D',(#339,#393,#447,#451),#305,.T.) ; +#490=ADVANCED_FACE('52D',(#489),#457,.F.) ; +#507=ADVANCED_FACE('52D',(#506),#495,.T.) ; +#540=ADVANCED_FACE('52D',(#539),#512,.F.) ; +#611=ADVANCED_FACE('52D',(#556,#610),#545,.T.) ; +#633=ADVANCED_FACE('52D',(#632),#616,.F.) ; +#645=ADVANCED_FACE('52D',(#644),#638,.F.) ; +#667=ADVANCED_FACE('52D',(#666),#650,.F.) ; +#679=ADVANCED_FACE('52D',(#678),#672,.F.) ; +#750=ADVANCED_FACE('52D',(#695,#749),#684,.T.) ; +#762=ADVANCED_FACE('52D',(#761),#755,.T.) ; +#784=ADVANCED_FACE('52D',(#783),#767,.F.) ; +#796=ADVANCED_FACE('52D',(#795),#789,.F.) ; +#873=ADVANCED_FACE('870',(#854,#872),#836,.F.) ; +#904=ADVANCED_FACE('870',(#903),#878,.T.) ; +#921=ADVANCED_FACE('870',(#920),#909,.T.) ; +#931=ADVANCED_FACE('870',(#930),#926,.F.) ; +#962=ADVANCED_FACE('870',(#961),#936,.T.) ; +#979=ADVANCED_FACE('870',(#978),#967,.T.) ; +#1003=ADVANCED_FACE('870',(#1002),#984,.T.) ; +#1025=ADVANCED_FACE('870',(#1024),#1008,.T.) ; +#1037=ADVANCED_FACE('870',(#1036),#1030,.T.) ; +#1122=ADVANCED_FACE('79A',(#1103,#1121),#1069,.F.) ; +#1153=ADVANCED_FACE('79A',(#1152),#1127,.T.) ; +#1177=ADVANCED_FACE('79A',(#1176),#1158,.T.) ; +#1201=ADVANCED_FACE('79A',(#1200),#1182,.T.) ; +#1218=ADVANCED_FACE('79A',(#1217),#1206,.T.) ; +#1267=ADVANCED_FACE('79A',(#1266),#1223,.T.) ; +#1300=ADVANCED_FACE('79A',(#1299),#1272,.T.) ; +#1333=ADVANCED_FACE('79A',(#1332),#1305,.T.) ; +#1350=ADVANCED_FACE('79A',(#1349),#1338,.T.) ; +#1381=ADVANCED_FACE('79A',(#1380),#1355,.F.) ; +#1398=ADVANCED_FACE('79A',(#1397),#1386,.F.) ; +#1428=ADVANCED_FACE('79A',(#1409,#1427),#1403,.F.) ; +#1450=ADVANCED_FACE('79A',(#1449),#1433,.T.) ; +#1462=ADVANCED_FACE('79A',(#1461),#1455,.T.) ; +#4=APPLICATION_PROTOCOL_DEFINITION('international standard','config_control_design',1994,#1) ; +#35=APPROVAL_DATE_TIME(#13,#24) ; +#77=B_SPLINE_CURVE_WITH_KNOTS('',5,(#78,#79,#80,#81,#82,#83,#84,#85,#86,#87,#88,#89,#90,#91,#92),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,6),(-7.85398163397,-3.92699081699,4.4408920985E-016,3.92699081699,7.85398163397),.UNSPECIFIED.) ; +#103=B_SPLINE_CURVE_WITH_KNOTS('',5,(#104,#105,#106,#107,#108,#109,#110,#111,#112,#113,#114,#115,#116,#117,#118),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,6),(-7.85398163397,-3.92699081699,4.4408920985E-016,3.92699081699,7.85398163397),.UNSPECIFIED.) ; +#188=B_SPLINE_CURVE_WITH_KNOTS('',5,(#189,#190,#191,#192,#193,#194,#195,#196,#197,#198,#199,#200,#201,#202,#203,#204,#205,#206,#207,#208,#209),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292074105,7.74584148254,11.6187622392,15.491683003,19.3646037458,22.2140874796),.UNSPECIFIED.) ; +#215=B_SPLINE_CURVE_WITH_KNOTS('',5,(#216,#217,#218,#219,#220,#221,#222,#223,#224,#225,#226,#227,#228,#229,#230,#231,#232,#233,#234,#235,#236),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292073664,7.74584148307,11.618762234,15.4916829903,19.3646037494,22.2140874992),.UNSPECIFIED.) ; +#242=B_SPLINE_CURVE_WITH_KNOTS('',5,(#243,#244,#245,#246,#247,#248,#249,#250,#251,#252,#253,#254,#255,#256,#257,#258,#259,#260,#261,#262,#263),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292073819,7.74584148132,11.6187622256,15.4916829835,19.3646037405,22.2140874761),.UNSPECIFIED.) ; +#269=B_SPLINE_CURVE_WITH_KNOTS('',5,(#270,#271,#272,#273,#274,#275,#276,#277,#278,#279,#280,#281,#282,#283,#284,#285,#286,#287,#288,#289,#290),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292075057,7.74584151084,11.6187622719,15.4916830411,19.3646038008,22.2140875287),.UNSPECIFIED.) ; +#340=B_SPLINE_CURVE_WITH_KNOTS('',5,(#341,#342,#343,#344,#345,#346,#347,#348,#349,#350,#351,#352,#353,#354,#355,#356,#357,#358,#359,#360,#361),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292073822,7.74584148135,11.6187622256,15.4916829836,19.3646037407,22.2140874763),.UNSPECIFIED.) ; +#367=B_SPLINE_CURVE_WITH_KNOTS('',5,(#368,#369,#370,#371,#372,#373,#374,#375,#376,#377,#378,#379,#380,#381,#382,#383,#384,#385,#386,#387,#388),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292075092,7.74584151105,11.6187622721,15.4916830414,19.3646038011,22.2140875291),.UNSPECIFIED.) ; +#394=B_SPLINE_CURVE_WITH_KNOTS('',5,(#395,#396,#397,#398,#399,#400,#401,#402,#403,#404,#405,#406,#407,#408,#409,#410,#411,#412,#413,#414,#415),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292074096,7.74584148236,11.618762239,15.4916830028,19.3646037456,22.2140874794),.UNSPECIFIED.) ; +#421=B_SPLINE_CURVE_WITH_KNOTS('',5,(#422,#423,#424,#425,#426,#427,#428,#429,#430,#431,#432,#433,#434,#435,#436,#437,#438,#439,#440,#441,#442),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292073663,7.74584148308,11.618762234,15.4916829903,19.3646037495,22.2140874992),.UNSPECIFIED.) ; +#557=B_SPLINE_CURVE_WITH_KNOTS('',5,(#558,#559,#560,#561,#562,#563,#564,#565,#566,#567,#568,#569,#570,#571,#572,#573,#574,#575,#576,#577,#578),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292075072,7.74584150645,11.6187622749,15.4916830251,19.3646037577,22.2140874912),.UNSPECIFIED.) ; +#584=B_SPLINE_CURVE_WITH_KNOTS('',5,(#585,#586,#587,#588,#589,#590,#591,#592,#593,#594,#595,#596,#597,#598,#599,#600,#601,#602,#603,#604,#605),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292075073,7.74584150644,11.6187622749,15.4916830252,19.3646037579,22.2140874915),.UNSPECIFIED.) ; +#696=B_SPLINE_CURVE_WITH_KNOTS('',5,(#697,#698,#699,#700,#701,#702,#703,#704,#705,#706,#707,#708,#709,#710,#711,#712,#713,#714,#715,#716,#717),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292075098,7.74584150689,11.6187622753,15.4916830257,19.3646037583,22.2140874919),.UNSPECIFIED.) ; +#723=B_SPLINE_CURVE_WITH_KNOTS('',5,(#724,#725,#726,#727,#728,#729,#730,#731,#732,#733,#734,#735,#736,#737,#738,#739,#740,#741,#742,#743,#744),.UNSPECIFIED.,.F.,.U.,(6,3,3,3,3,3,6),(0.,3.87292075071,7.74584150651,11.6187622749,15.4916830252,19.3646037577,22.2140874913),.UNSPECIFIED.) ; +#1224=B_SPLINE_CURVE_WITH_KNOTS('',5,(#1225,#1226,#1227,#1228,#1229,#1230,#1231,#1232,#1233,#1234,#1235,#1236),.UNSPECIFIED.,.F.,.U.,(6,3,3,6),(0.,1.01728776527,2.03457553053,2.69111206366),.UNSPECIFIED.) ; +#1240=B_SPLINE_CURVE_WITH_KNOTS('',5,(#1241,#1242,#1243,#1244,#1245,#1246,#1247,#1248,#1249,#1250,#1251,#1252),.UNSPECIFIED.,.F.,.U.,(6,3,3,6),(0.,1.01728776527,2.03457553053,2.69111206365),.UNSPECIFIED.) ; +#1273=B_SPLINE_CURVE_WITH_KNOTS('',5,(#1274,#1275,#1276,#1277,#1278,#1279,#1280,#1281,#1282,#1283,#1284,#1285),.UNSPECIFIED.,.F.,.U.,(6,3,3,6),(0.,1.01728776527,2.03457553053,2.69111206365),.UNSPECIFIED.) ; +#1306=B_SPLINE_CURVE_WITH_KNOTS('',5,(#1307,#1308,#1309,#1310,#1311,#1312,#1313,#1314,#1315,#1316,#1317,#1318),.UNSPECIFIED.,.F.,.U.,(6,3,3,6),(0.,1.01728776527,2.03457553054,2.69111206366),.UNSPECIFIED.) ; +#797=MANIFOLD_SOLID_BREP('52D',#62) ; +#1038=MANIFOLD_SOLID_BREP('870',#831) ; +#1463=MANIFOLD_SOLID_BREP('79A',#1064) ; +#11=CALENDAR_DATE(2014,9,11) ; +#33=CC_DESIGN_APPROVAL(#24,(#19,#6,#17)) ; +#21=CC_DESIGN_DATE_AND_TIME_ASSIGNMENT(#13,#20,(#19)) ; +#32=CC_DESIGN_DATE_AND_TIME_ASSIGNMENT(#13,#31,(#17)) ; +#20=DATE_TIME_ROLE('classification_date') ; +#31=DATE_TIME_ROLE('creation_date') ; +#30=CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT(#28,#29,(#19)) ; +#36=CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT(#28,#37,(#6)) ; +#38=CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT(#28,#39,(#6,#17)) ; +#40=CC_DESIGN_PERSON_AND_ORGANIZATION_ASSIGNMENT(#28,#41,(#5)) ; +#29=PERSON_AND_ORGANIZATION_ROLE('classification_officer') ; +#37=PERSON_AND_ORGANIZATION_ROLE('design_supplier') ; +#39=PERSON_AND_ORGANIZATION_ROLE('creator') ; +#41=PERSON_AND_ORGANIZATION_ROLE('design_owner') ; +#42=CC_DESIGN_SECURITY_CLASSIFICATION(#19,(#6,#800,#1041,#1466,#1479,#1494)) ; +#60=DOCUMENT('1','L-BRACKET.CATPart','CATPart document',#59) ; +#829=DOCUMENT('2','BOLT.CATPart','CATPart document',#828) ; +#1062=DOCUMENT('3','NUT.CATPart','CATPart document',#1061) ; +#59=DOCUMENT_TYPE('') ; +#828=DOCUMENT_TYPE('') ; +#1061=DOCUMENT_TYPE('') ; +#135=CIRCLE('generated circle',#134,5.) ; +#140=CIRCLE('generated circle',#139,5.) ; +#840=CIRCLE('generated circle',#839,7.5) ; +#849=CIRCLE('generated circle',#848,7.5) ; +#858=CIRCLE('generated circle',#857,5.) ; +#867=CIRCLE('generated circle',#866,5.) ; +#889=CIRCLE('generated circle',#888,5.) ; +#913=CIRCLE('generated circle',#912,5.) ; +#954=CIRCLE('generated circle',#953,7.5) ; +#971=CIRCLE('generated circle',#970,7.5) ; +#988=CIRCLE('generated circle',#987,5.5) ; +#997=CIRCLE('generated circle',#996,5.5) ; +#1012=CIRCLE('generated circle',#1011,2.) ; +#1017=CIRCLE('generated circle',#1016,2.) ; +#1107=CIRCLE('generated circle',#1106,5.) ; +#1116=CIRCLE('generated circle',#1115,5.) ; +#1359=CIRCLE('generated circle',#1358,5.) ; +#1390=CIRCLE('generated circle',#1389,5.) ; +#1413=CIRCLE('generated circle',#1412,6.) ; +#1422=CIRCLE('generated circle',#1421,6.) ; +#1437=CIRCLE('generated circle',#1436,1.) ; +#1442=CIRCLE('generated circle',#1441,1.) ; +#802=CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#803,#801) ; +#1043=CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#1044,#1042) ; +#1468=CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#1469,#1467) ; +#1481=CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#1482,#1480) ; +#1496=CONTEXT_DEPENDENT_SHAPE_REPRESENTATION(#1497,#1495) ; +#799=SHAPE_REPRESENTATION_RELATIONSHIP(' ',' ',#54,#798) ; +#1040=SHAPE_REPRESENTATION_RELATIONSHIP(' ',' ',#823,#1039) ; +#1465=SHAPE_REPRESENTATION_RELATIONSHIP(' ',' ',#1056,#1464) ; +#67=CYLINDRICAL_SURFACE('generated cylinder',#66,5.) ; +#131=CYLINDRICAL_SURFACE('generated cylinder',#130,5.) ; +#616=CYLINDRICAL_SURFACE('generated cylinder',#615,5.) ; +#638=CYLINDRICAL_SURFACE('generated cylinder',#637,5.) ; +#650=CYLINDRICAL_SURFACE('generated cylinder',#649,5.) ; +#672=CYLINDRICAL_SURFACE('generated cylinder',#671,5.) ; +#767=CYLINDRICAL_SURFACE('generated cylinder',#766,5.) ; +#789=CYLINDRICAL_SURFACE('generated cylinder',#788,5.) ; +#878=CYLINDRICAL_SURFACE('generated cylinder',#877,5.) ; +#909=CYLINDRICAL_SURFACE('generated cylinder',#908,5.) ; +#936=CYLINDRICAL_SURFACE('generated cylinder',#935,7.5) ; +#967=CYLINDRICAL_SURFACE('generated cylinder',#966,7.5) ; +#1223=CYLINDRICAL_SURFACE('generated cylinder',#1222,1.) ; +#1272=CYLINDRICAL_SURFACE('generated cylinder',#1271,1.) ; +#1305=CYLINDRICAL_SURFACE('generated cylinder',#1304,1.) ; +#1338=CYLINDRICAL_SURFACE('generated cylinder',#1337,1.) ; +#1355=CYLINDRICAL_SURFACE('generated cylinder',#1354,5.) ; +#1386=CYLINDRICAL_SURFACE('generated cylinder',#1385,5.) ; +#1008=TOROIDAL_SURFACE('homeo Torus',#1007,5.5,2.) ; +#1030=TOROIDAL_SURFACE('homeo Torus',#1029,5.5,2.) ; +#1433=TOROIDAL_SURFACE('homeo Torus',#1432,6.,1.) ; +#1455=TOROIDAL_SURFACE('homeo Torus',#1454,6.,1.) ; +#3=DESIGN_CONTEXT(' ',#1,'design') ; +#76=EDGE_CURVE('',#73,#75,#71,.F.) ; +#95=EDGE_CURVE('',#94,#73,#77,.T.) ; +#102=EDGE_CURVE('',#101,#94,#99,.T.) ; +#119=EDGE_CURVE('',#75,#101,#103,.T.) ; +#136=EDGE_CURVE('',#101,#75,#135,.T.) ; +#141=EDGE_CURVE('',#73,#94,#140,.F.) ; +#162=EDGE_CURVE('',#159,#161,#157,.T.) ; +#169=EDGE_CURVE('',#168,#161,#166,.T.) ; +#176=EDGE_CURVE('',#175,#168,#173,.T.) ; +#181=EDGE_CURVE('',#175,#159,#180,.T.) ; +#214=EDGE_CURVE('',#211,#213,#188,.T.) ; +#237=EDGE_CURVE('',#213,#211,#215,.T.) ; +#268=EDGE_CURVE('',#265,#267,#242,.T.) ; +#291=EDGE_CURVE('',#267,#265,#269,.T.) ; +#314=EDGE_CURVE('',#311,#313,#309,.T.) ; +#321=EDGE_CURVE('',#320,#313,#318,.T.) ; +#328=EDGE_CURVE('',#327,#320,#325,.T.) ; +#333=EDGE_CURVE('',#327,#311,#332,.T.) ; +#366=EDGE_CURVE('',#363,#365,#340,.T.) ; +#389=EDGE_CURVE('',#365,#363,#367,.T.) ; +#420=EDGE_CURVE('',#417,#419,#394,.T.) ; +#443=EDGE_CURVE('',#419,#417,#421,.T.) ; +#462=EDGE_CURVE('',#161,#311,#461,.T.) ; +#469=EDGE_CURVE('',#468,#159,#466,.T.) ; +#476=EDGE_CURVE('',#475,#468,#473,.T.) ; +#481=EDGE_CURVE('',#313,#475,#480,.T.) ; +#500=EDGE_CURVE('',#168,#327,#499,.T.) ; +#519=EDGE_CURVE('',#320,#518,#516,.T.) ; +#526=EDGE_CURVE('',#518,#525,#523,.T.) ; +#531=EDGE_CURVE('',#525,#175,#530,.T.) ; +#550=EDGE_CURVE('',#525,#468,#549,.T.) ; +#583=EDGE_CURVE('',#580,#582,#557,.T.) ; +#606=EDGE_CURVE('',#582,#580,#584,.T.) ; +#621=EDGE_CURVE('',#213,#363,#620,.F.) ; +#626=EDGE_CURVE('',#365,#211,#625,.T.) ; +#655=EDGE_CURVE('',#267,#417,#654,.F.) ; +#660=EDGE_CURVE('',#419,#265,#659,.T.) ; +#689=EDGE_CURVE('',#518,#475,#688,.T.) ; +#722=EDGE_CURVE('',#719,#721,#696,.T.) ; +#745=EDGE_CURVE('',#721,#719,#723,.T.) ; +#772=EDGE_CURVE('',#582,#719,#771,.F.) ; +#777=EDGE_CURVE('',#721,#580,#776,.T.) ; +#845=EDGE_CURVE('',#842,#844,#840,.T.) ; +#850=EDGE_CURVE('',#844,#842,#849,.T.) ; +#863=EDGE_CURVE('',#860,#862,#858,.T.) ; +#868=EDGE_CURVE('',#862,#860,#867,.T.) ; +#885=EDGE_CURVE('',#860,#884,#882,.T.) ; +#892=EDGE_CURVE('',#884,#891,#889,.F.) ; +#897=EDGE_CURVE('',#891,#862,#896,.F.) ; +#914=EDGE_CURVE('',#891,#884,#913,.F.) ; +#943=EDGE_CURVE('',#842,#942,#940,.T.) ; +#950=EDGE_CURVE('',#949,#844,#947,.F.) ; +#955=EDGE_CURVE('',#949,#942,#954,.F.) ; +#972=EDGE_CURVE('',#942,#949,#971,.F.) ; +#993=EDGE_CURVE('',#990,#992,#988,.F.) ; +#998=EDGE_CURVE('',#992,#990,#997,.F.) ; +#1013=EDGE_CURVE('',#942,#990,#1012,.T.) ; +#1018=EDGE_CURVE('',#949,#992,#1017,.T.) ; +#1078=EDGE_CURVE('',#1075,#1077,#1073,.T.) ; +#1085=EDGE_CURVE('',#1084,#1075,#1082,.T.) ; +#1092=EDGE_CURVE('',#1091,#1084,#1089,.T.) ; +#1097=EDGE_CURVE('',#1077,#1091,#1096,.T.) ; +#1112=EDGE_CURVE('',#1109,#1111,#1107,.T.) ; +#1117=EDGE_CURVE('',#1111,#1109,#1116,.T.) ; +#1134=EDGE_CURVE('',#1133,#1075,#1131,.T.) ; +#1141=EDGE_CURVE('',#1140,#1077,#1138,.T.) ; +#1146=EDGE_CURVE('',#1140,#1133,#1145,.F.) ; +#1165=EDGE_CURVE('',#1164,#1084,#1162,.T.) ; +#1170=EDGE_CURVE('',#1133,#1164,#1169,.F.) ; +#1189=EDGE_CURVE('',#1188,#1091,#1186,.T.) ; +#1194=EDGE_CURVE('',#1164,#1188,#1193,.T.) ; +#1211=EDGE_CURVE('',#1188,#1140,#1210,.F.) ; +#1239=EDGE_CURVE('',#1238,#1188,#1224,.T.) ; +#1255=EDGE_CURVE('',#1164,#1254,#1240,.F.) ; +#1260=EDGE_CURVE('',#1254,#1238,#1259,.T.) ; +#1288=EDGE_CURVE('',#1287,#1140,#1273,.T.) ; +#1293=EDGE_CURVE('',#1238,#1287,#1292,.F.) ; +#1321=EDGE_CURVE('',#1320,#1133,#1306,.T.) ; +#1326=EDGE_CURVE('',#1287,#1320,#1325,.F.) ; +#1343=EDGE_CURVE('',#1320,#1254,#1342,.F.) ; +#1364=EDGE_CURVE('',#1361,#1363,#1359,.T.) ; +#1369=EDGE_CURVE('',#1111,#1361,#1368,.F.) ; +#1374=EDGE_CURVE('',#1363,#1109,#1373,.T.) ; +#1391=EDGE_CURVE('',#1363,#1361,#1390,.T.) ; +#1418=EDGE_CURVE('',#1415,#1417,#1413,.T.) ; +#1423=EDGE_CURVE('',#1417,#1415,#1422,.T.) ; +#1438=EDGE_CURVE('',#1415,#1361,#1437,.F.) ; +#1443=EDGE_CURVE('',#1417,#1363,#1442,.F.) ; +#120=EDGE_LOOP('',(#121,#122,#123,#124)) ; +#142=EDGE_LOOP('',(#143,#144,#145,#146)) ; +#182=EDGE_LOOP('',(#183,#184,#185,#186)) ; +#238=EDGE_LOOP('',(#239,#240)) ; +#292=EDGE_LOOP('',(#293,#294)) ; +#296=EDGE_LOOP('',(#297,#298)) ; +#334=EDGE_LOOP('',(#335,#336,#337,#338)) ; +#390=EDGE_LOOP('',(#391,#392)) ; +#444=EDGE_LOOP('',(#445,#446)) ; +#448=EDGE_LOOP('',(#449,#450)) ; +#482=EDGE_LOOP('',(#483,#484,#485,#486,#487,#488)) ; +#501=EDGE_LOOP('',(#502,#503,#504,#505)) ; +#532=EDGE_LOOP('',(#533,#534,#535,#536,#537,#538)) ; +#551=EDGE_LOOP('',(#552,#553,#554,#555)) ; +#607=EDGE_LOOP('',(#608,#609)) ; +#627=EDGE_LOOP('',(#628,#629,#630,#631)) ; +#639=EDGE_LOOP('',(#640,#641,#642,#643)) ; +#661=EDGE_LOOP('',(#662,#663,#664,#665)) ; +#673=EDGE_LOOP('',(#674,#675,#676,#677)) ; +#690=EDGE_LOOP('',(#691,#692,#693,#694)) ; +#746=EDGE_LOOP('',(#747,#748)) ; +#756=EDGE_LOOP('',(#757,#758,#759,#760)) ; +#778=EDGE_LOOP('',(#779,#780,#781,#782)) ; +#790=EDGE_LOOP('',(#791,#792,#793,#794)) ; +#851=EDGE_LOOP('',(#852,#853)) ; +#869=EDGE_LOOP('',(#870,#871)) ; +#898=EDGE_LOOP('',(#899,#900,#901,#902)) ; +#915=EDGE_LOOP('',(#916,#917,#918,#919)) ; +#927=EDGE_LOOP('',(#928,#929)) ; +#956=EDGE_LOOP('',(#957,#958,#959,#960)) ; +#973=EDGE_LOOP('',(#974,#975,#976,#977)) ; +#999=EDGE_LOOP('',(#1000,#1001)) ; +#1019=EDGE_LOOP('',(#1020,#1021,#1022,#1023)) ; +#1031=EDGE_LOOP('',(#1032,#1033,#1034,#1035)) ; +#1098=EDGE_LOOP('',(#1099,#1100,#1101,#1102)) ; +#1118=EDGE_LOOP('',(#1119,#1120)) ; +#1147=EDGE_LOOP('',(#1148,#1149,#1150,#1151)) ; +#1171=EDGE_LOOP('',(#1172,#1173,#1174,#1175)) ; +#1195=EDGE_LOOP('',(#1196,#1197,#1198,#1199)) ; +#1212=EDGE_LOOP('',(#1213,#1214,#1215,#1216)) ; +#1261=EDGE_LOOP('',(#1262,#1263,#1264,#1265)) ; +#1294=EDGE_LOOP('',(#1295,#1296,#1297,#1298)) ; +#1327=EDGE_LOOP('',(#1328,#1329,#1330,#1331)) ; +#1344=EDGE_LOOP('',(#1345,#1346,#1347,#1348)) ; +#1375=EDGE_LOOP('',(#1376,#1377,#1378,#1379)) ; +#1392=EDGE_LOOP('',(#1393,#1394,#1395,#1396)) ; +#1404=EDGE_LOOP('',(#1405,#1406,#1407,#1408)) ; +#1424=EDGE_LOOP('',(#1425,#1426)) ; +#1444=EDGE_LOOP('',(#1445,#1446,#1447,#1448)) ; +#1456=EDGE_LOOP('',(#1457,#1458,#1459,#1460)) ; +#125=FACE_OUTER_BOUND('',#120,.T.) ; +#147=FACE_OUTER_BOUND('',#142,.T.) ; +#187=FACE_OUTER_BOUND('',#182,.T.) ; +#339=FACE_OUTER_BOUND('',#334,.T.) ; +#489=FACE_OUTER_BOUND('',#482,.T.) ; +#506=FACE_OUTER_BOUND('',#501,.T.) ; +#539=FACE_OUTER_BOUND('',#532,.T.) ; +#556=FACE_OUTER_BOUND('',#551,.T.) ; +#632=FACE_OUTER_BOUND('',#627,.T.) ; +#644=FACE_OUTER_BOUND('',#639,.T.) ; +#666=FACE_OUTER_BOUND('',#661,.T.) ; +#678=FACE_OUTER_BOUND('',#673,.T.) ; +#695=FACE_OUTER_BOUND('',#690,.T.) ; +#761=FACE_OUTER_BOUND('',#756,.T.) ; +#783=FACE_OUTER_BOUND('',#778,.T.) ; +#795=FACE_OUTER_BOUND('',#790,.T.) ; +#854=FACE_OUTER_BOUND('',#851,.T.) ; +#903=FACE_OUTER_BOUND('',#898,.T.) ; +#920=FACE_OUTER_BOUND('',#915,.T.) ; +#930=FACE_OUTER_BOUND('',#927,.T.) ; +#961=FACE_OUTER_BOUND('',#956,.T.) ; +#978=FACE_OUTER_BOUND('',#973,.T.) ; +#1002=FACE_OUTER_BOUND('',#999,.T.) ; +#1024=FACE_OUTER_BOUND('',#1019,.T.) ; +#1036=FACE_OUTER_BOUND('',#1031,.T.) ; +#1103=FACE_OUTER_BOUND('',#1098,.T.) ; +#1152=FACE_OUTER_BOUND('',#1147,.T.) ; +#1176=FACE_OUTER_BOUND('',#1171,.T.) ; +#1200=FACE_OUTER_BOUND('',#1195,.T.) ; +#1217=FACE_OUTER_BOUND('',#1212,.T.) ; +#1266=FACE_OUTER_BOUND('',#1261,.T.) ; +#1299=FACE_OUTER_BOUND('',#1294,.T.) ; +#1332=FACE_OUTER_BOUND('',#1327,.T.) ; +#1349=FACE_OUTER_BOUND('',#1344,.T.) ; +#1380=FACE_OUTER_BOUND('',#1375,.T.) ; +#1397=FACE_OUTER_BOUND('',#1392,.T.) ; +#1409=FACE_OUTER_BOUND('',#1404,.T.) ; +#1449=FACE_OUTER_BOUND('',#1444,.T.) ; +#1461=FACE_OUTER_BOUND('',#1456,.T.) ; +#50=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.005),#46,'distance_accuracy_value','CONFUSED CURVE UNCERTAINTY') ; +#52=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.005),#46,'distance_accuracy_value','CONFUSED CURVE UNCERTAINTY') ; +#813=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.005),#46,'distance_accuracy_value','CONFUSED CURVE UNCERTAINTY') ; +#821=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.005),#46,'distance_accuracy_value','CONFUSED CURVE UNCERTAINTY') ; +#1054=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.005),#46,'distance_accuracy_value','CONFUSED CURVE UNCERTAINTY') ; +#1492=UNCERTAINTY_MEASURE_WITH_UNIT(LENGTH_MEASURE(0.005),#46,'distance_accuracy_value','CONFUSED CURVE UNCERTAINTY') ; +#71=LINE('Line',#68,#70) ; +#99=LINE('Line',#96,#98) ; +#157=LINE('Line',#154,#156) ; +#166=LINE('Line',#163,#165) ; +#173=LINE('Line',#170,#172) ; +#180=LINE('Line',#177,#179) ; +#309=LINE('Line',#306,#308) ; +#318=LINE('Line',#315,#317) ; +#325=LINE('Line',#322,#324) ; +#332=LINE('Line',#329,#331) ; +#461=LINE('Line',#458,#460) ; +#466=LINE('Line',#463,#465) ; +#473=LINE('Line',#470,#472) ; +#480=LINE('Line',#477,#479) ; +#499=LINE('Line',#496,#498) ; +#516=LINE('Line',#513,#515) ; +#523=LINE('Line',#520,#522) ; +#530=LINE('Line',#527,#529) ; +#549=LINE('Line',#546,#548) ; +#620=LINE('Line',#617,#619) ; +#625=LINE('Line',#622,#624) ; +#654=LINE('Line',#651,#653) ; +#659=LINE('Line',#656,#658) ; +#688=LINE('Line',#685,#687) ; +#771=LINE('Line',#768,#770) ; +#776=LINE('Line',#773,#775) ; +#882=LINE('Line',#879,#881) ; +#896=LINE('Line',#893,#895) ; +#940=LINE('Line',#937,#939) ; +#947=LINE('Line',#944,#946) ; +#1073=LINE('Line',#1070,#1072) ; +#1082=LINE('Line',#1079,#1081) ; +#1089=LINE('Line',#1086,#1088) ; +#1096=LINE('Line',#1093,#1095) ; +#1131=LINE('Line',#1128,#1130) ; +#1138=LINE('Line',#1135,#1137) ; +#1145=LINE('Line',#1142,#1144) ; +#1162=LINE('Line',#1159,#1161) ; +#1169=LINE('Line',#1166,#1168) ; +#1186=LINE('Line',#1183,#1185) ; +#1193=LINE('Line',#1190,#1192) ; +#1210=LINE('Line',#1207,#1209) ; +#1259=LINE('Line',#1256,#1258) ; +#1292=LINE('Line',#1289,#1291) ; +#1325=LINE('Line',#1322,#1324) ; +#1342=LINE('Line',#1339,#1341) ; +#1368=LINE('Line',#1365,#1367) ; +#1373=LINE('Line',#1370,#1372) ; +#2=MECHANICAL_CONTEXT(' ',#1,'mechanical') ; +#800=NEXT_ASSEMBLY_USAGE_OCCURRENCE('NAUO2','NAUO2','L-BRACKET_1',#17,#58,' ') ; +#1041=NEXT_ASSEMBLY_USAGE_OCCURRENCE('NAUO3','NAUO3','BOLT_1',#819,#827,' ') ; +#1466=NEXT_ASSEMBLY_USAGE_OCCURRENCE('NAUO4','NAUO4','NUT_1',#819,#1060,' ') ; +#1479=NEXT_ASSEMBLY_USAGE_OCCURRENCE('NAUO5','NAUO5','NUT-BOLT ASSEMBLY_1',#17,#819,' ') ; +#1494=NEXT_ASSEMBLY_USAGE_OCCURRENCE('NAUO6','NAUO6','NUT-BOLT ASSEMBLY_2',#17,#819,' ') ; +#27=PERSONAL_ADDRESS(' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',(#25),' ') ; +#153=PLANE('Plane',#152) ; +#305=PLANE('Plane',#304) ; +#457=PLANE('Plane',#456) ; +#495=PLANE('Plane',#494) ; +#512=PLANE('Plane',#511) ; +#545=PLANE('Plane',#544) ; +#684=PLANE('Plane',#683) ; +#755=PLANE('Plane',#754) ; +#836=PLANE('Plane',#835) ; +#926=PLANE('Plane',#925) ; +#984=PLANE('Plane',#983) ; +#1069=PLANE('Plane',#1068) ; +#1127=PLANE('Plane',#1126) ; +#1158=PLANE('Plane',#1157) ; +#1182=PLANE('Plane',#1181) ; +#1206=PLANE('Plane',#1205) ; +#1403=PLANE('Plane',#1402) ; +#48=PLANE_ANGLE_MEASURE_WITH_UNIT(PLANE_ANGLE_MEASURE(0.0174532925199),#47) ; +#7=PRODUCT_CATEGORY('part',$) ; +#14=PRODUCT_CATEGORY('part',$) ; +#9=PRODUCT_CATEGORY_RELATIONSHIP(' ',' ',#7,#8) ; +#16=PRODUCT_CATEGORY_RELATIONSHIP(' ',' ',#14,#15) ; +#6=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('None',' ',#5,.BOUGHT.) ; +#57=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('None',' ',#56,.BOUGHT.) ; +#818=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('None',' ',#817,.BOUGHT.) ; +#826=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('None',' ',#825,.BOUGHT.) ; +#1059=PRODUCT_DEFINITION_FORMATION_WITH_SPECIFIED_SOURCE('None',' ',#1058,.BOUGHT.) ; +#58=PRODUCT_DEFINITION_WITH_ASSOCIATED_DOCUMENTS('None',' ',#57,#3,(#60)) ; +#827=PRODUCT_DEFINITION_WITH_ASSOCIATED_DOCUMENTS('None',' ',#826,#3,(#829)) ; +#1060=PRODUCT_DEFINITION_WITH_ASSOCIATED_DOCUMENTS('None',' ',#1059,#3,(#1062)) ; +#8=PRODUCT_RELATED_PRODUCT_CATEGORY('detail',$,(#56,#825,#1058)) ; +#15=PRODUCT_RELATED_PRODUCT_CATEGORY('part',$,(#5,#817)) ; +#43=SHAPE_DEFINITION_REPRESENTATION(#45,#44) ; +#55=SHAPE_DEFINITION_REPRESENTATION(#61,#54) ; +#816=SHAPE_DEFINITION_REPRESENTATION(#820,#815) ; +#824=SHAPE_DEFINITION_REPRESENTATION(#830,#823) ; +#1057=SHAPE_DEFINITION_REPRESENTATION(#1063,#1056) ; +#73=VERTEX_POINT('',#72) ; +#75=VERTEX_POINT('',#74) ; +#94=VERTEX_POINT('',#93) ; +#101=VERTEX_POINT('',#100) ; +#159=VERTEX_POINT('',#158) ; +#161=VERTEX_POINT('',#160) ; +#168=VERTEX_POINT('',#167) ; +#175=VERTEX_POINT('',#174) ; +#211=VERTEX_POINT('',#210) ; +#213=VERTEX_POINT('',#212) ; +#265=VERTEX_POINT('',#264) ; +#267=VERTEX_POINT('',#266) ; +#311=VERTEX_POINT('',#310) ; +#313=VERTEX_POINT('',#312) ; +#320=VERTEX_POINT('',#319) ; +#327=VERTEX_POINT('',#326) ; +#363=VERTEX_POINT('',#362) ; +#365=VERTEX_POINT('',#364) ; +#417=VERTEX_POINT('',#416) ; +#419=VERTEX_POINT('',#418) ; +#468=VERTEX_POINT('',#467) ; +#475=VERTEX_POINT('',#474) ; +#518=VERTEX_POINT('',#517) ; +#525=VERTEX_POINT('',#524) ; +#580=VERTEX_POINT('',#579) ; +#582=VERTEX_POINT('',#581) ; +#719=VERTEX_POINT('',#718) ; +#721=VERTEX_POINT('',#720) ; +#842=VERTEX_POINT('',#841) ; +#844=VERTEX_POINT('',#843) ; +#860=VERTEX_POINT('',#859) ; +#862=VERTEX_POINT('',#861) ; +#884=VERTEX_POINT('',#883) ; +#891=VERTEX_POINT('',#890) ; +#942=VERTEX_POINT('',#941) ; +#949=VERTEX_POINT('',#948) ; +#990=VERTEX_POINT('',#989) ; +#992=VERTEX_POINT('',#991) ; +#1075=VERTEX_POINT('',#1074) ; +#1077=VERTEX_POINT('',#1076) ; +#1084=VERTEX_POINT('',#1083) ; +#1091=VERTEX_POINT('',#1090) ; +#1109=VERTEX_POINT('',#1108) ; +#1111=VERTEX_POINT('',#1110) ; +#1133=VERTEX_POINT('',#1132) ; +#1140=VERTEX_POINT('',#1139) ; +#1164=VERTEX_POINT('',#1163) ; +#1188=VERTEX_POINT('',#1187) ; +#1238=VERTEX_POINT('',#1237) ; +#1254=VERTEX_POINT('',#1253) ; +#1287=VERTEX_POINT('',#1286) ; +#1320=VERTEX_POINT('',#1319) ; +#1361=VERTEX_POINT('',#1360) ; +#1363=VERTEX_POINT('',#1362) ; +#1415=VERTEX_POINT('',#1414) ; +#1417=VERTEX_POINT('',#1416) ; +#46=(LENGTH_UNIT()NAMED_UNIT(*)SI_UNIT(.MILLI.,.METRE.)) ; +#47=(NAMED_UNIT(*)PLANE_ANGLE_UNIT()SI_UNIT($,.RADIAN.)) ; +#49=(NAMED_UNIT(*)SI_UNIT($,.STERADIAN.)SOLID_ANGLE_UNIT()) ; +#51=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#50))GLOBAL_UNIT_ASSIGNED_CONTEXT((#46,#47,#49))REPRESENTATION_CONTEXT(' ',' ')) ; +#53=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#52))GLOBAL_UNIT_ASSIGNED_CONTEXT((#46,#47,#49))REPRESENTATION_CONTEXT(' ',' ')) ; +#814=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#813))GLOBAL_UNIT_ASSIGNED_CONTEXT((#46,#47,#49))REPRESENTATION_CONTEXT(' ',' ')) ; +#822=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#821))GLOBAL_UNIT_ASSIGNED_CONTEXT((#46,#47,#49))REPRESENTATION_CONTEXT(' ',' ')) ; +#1055=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#1054))GLOBAL_UNIT_ASSIGNED_CONTEXT((#46,#47,#49))REPRESENTATION_CONTEXT(' ',' ')) ; +#1493=(GEOMETRIC_REPRESENTATION_CONTEXT(3)GLOBAL_UNCERTAINTY_ASSIGNED_CONTEXT((#1492))GLOBAL_UNIT_ASSIGNED_CONTEXT((#46,#47,#49))REPRESENTATION_CONTEXT(' ',' ')) ; +#803=(REPRESENTATION_RELATIONSHIP(' ',' ',#54,#44)REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#804)SHAPE_REPRESENTATION_RELATIONSHIP()) ; +#1044=(REPRESENTATION_RELATIONSHIP(' ',' ',#823,#815)REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#1045)SHAPE_REPRESENTATION_RELATIONSHIP()) ; +#1469=(REPRESENTATION_RELATIONSHIP(' ',' ',#1056,#815)REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#1470)SHAPE_REPRESENTATION_RELATIONSHIP()) ; +#1482=(REPRESENTATION_RELATIONSHIP(' ',' ',#815,#44)REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#1483)SHAPE_REPRESENTATION_RELATIONSHIP()) ; +#1497=(REPRESENTATION_RELATIONSHIP(' ',' ',#815,#44)REPRESENTATION_RELATIONSHIP_WITH_TRANSFORMATION(#1498)SHAPE_REPRESENTATION_RELATIONSHIP()) ; +ENDSEC; +END-ISO-10303-21; diff --git a/src/3rdParty/salomesmesh/src/DriverSTL/DriverSTL_R_SMDS_Mesh.cpp b/src/3rdParty/salomesmesh/src/DriverSTL/DriverSTL_R_SMDS_Mesh.cpp index b22b28905..46a1dc7d2 100644 --- a/src/3rdParty/salomesmesh/src/DriverSTL/DriverSTL_R_SMDS_Mesh.cpp +++ b/src/3rdParty/salomesmesh/src/DriverSTL/DriverSTL_R_SMDS_Mesh.cpp @@ -157,6 +157,9 @@ Driver_Mesh::Status DriverSTL_R_SMDS_Mesh::Perform() // static methods +#pragma warning(push) +#pragma warning(disable : 4805) + static Standard_Real readFloat(OSD_File& theFile) { union { @@ -176,6 +179,7 @@ static Standard_Real readFloat(OSD_File& theFile) return u.f; } +#pragma warning(pop) static SMDS_MeshNode* addNode(const gp_Pnt& P, DriverSTL_DataMapOfPntNodePtr& uniqnodes, diff --git a/src/App/Application.cpp b/src/App/Application.cpp index e8adf1132..57da57783 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -94,7 +94,11 @@ #include "Annotation.h" #include "MeasureDistance.h" #include "Placement.h" -#include "Plane.h" +#include "GeoFeatureGroup.h" +#include "OriginGroup.h" +#include "Part.h" +#include "OriginFeature.h" +#include "Origin.h" #include "MaterialObject.h" #include "Expression.h" @@ -1128,7 +1132,14 @@ void Application::initTypes(void) App ::MaterialObject ::init(); App ::MaterialObjectPython ::init(); App ::Placement ::init(); + App ::OriginFeature ::init(); App ::Plane ::init(); + App ::Line ::init(); + App ::GeoFeatureGroup ::init(); + App ::GeoFeatureGroupPython ::init(); + App ::OriginGroup ::init(); + App ::Part ::init(); + App ::Origin ::init(); // Expression classes App ::Expression ::init(); @@ -1334,7 +1345,7 @@ void Application::processFiles(const std::list& files) Base::Interpreter().runFile(file.filePath().c_str(), true); } else if (file.hasExtension("py")) { - try { + try{ Base::Interpreter().loadModule(file.fileNamePure().c_str()); } catch(const PyException&) { diff --git a/src/App/CMakeLists.txt b/src/App/CMakeLists.txt index e03e21ec0..1fd9d474a 100644 --- a/src/App/CMakeLists.txt +++ b/src/App/CMakeLists.txt @@ -33,6 +33,11 @@ set(FreeCADApp_LIBS generate_from_xml(DocumentPy) generate_from_xml(DocumentObjectPy) generate_from_xml(DocumentObjectGroupPy) +generate_from_xml(GeoFeaturePy) +generate_from_xml(GeoFeatureGroupPy) +generate_from_xml(OriginGroupPy) +generate_from_xml(PartPy) + generate_from_xml(ComplexGeoDataPy) generate_from_xml(PropertyContainerPy) generate_from_xml(MaterialPy) @@ -43,6 +48,10 @@ generate_from_py(FreeCADTest TestScript.h) SET(FreeCADApp_XML_SRCS DocumentObjectGroupPy.xml DocumentObjectPy.xml + GeoFeaturePy.xml + GeoFeatureGroupPy.xml + OriginGroupPy.xml + PartPy.xml DocumentPy.xml PropertyContainerPy.xml ComplexGeoDataPy.xml @@ -58,6 +67,7 @@ SET(Document_CPP_SRCS DocumentObjectFileIncluded.cpp DocumentObjectGroup.cpp DocumentObjectGroupPyImp.cpp + GeoFeaturePyImp.cpp DocumentObjectPyImp.cpp DocumentObserver.cpp DocumentObserverPython.cpp @@ -66,10 +76,18 @@ SET(Document_CPP_SRCS FeaturePython.cpp FeatureTest.cpp GeoFeature.cpp + GeoFeatureGroupPyImp.cpp + GeoFeatureGroup.cpp + OriginGroupPyImp.cpp + OriginGroup.cpp + PartPyImp.cpp + Part.cpp + Origin.cpp + Path.cpp InventorObject.cpp MeasureDistance.cpp Placement.cpp - Plane.cpp + OriginFeature.cpp Range.cpp Transactions.cpp VRMLObject.cpp @@ -93,10 +111,15 @@ SET(Document_HPP_SRCS FeaturePythonPyImp.inl FeatureTest.h GeoFeature.h + GeoFeatureGroup.h + OriginGroup.h + Part.h + Origin.h + Path.h InventorObject.h MeasureDistance.h Placement.h - Plane.h + OriginFeature.h Range.h Transactions.h VRMLObject.h diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 4312724bd..0e026c0bf 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -74,7 +74,6 @@ recompute path. Also enables more complicated dependencies beyond trees. #include "DocumentPy.h" #include "Application.h" #include "DocumentObject.h" -#include "PropertyLinks.h" #include "MergeDocuments.h" #include @@ -110,7 +109,7 @@ using namespace zipios; #if FC_DEBUG # define FC_LOGFEATUREUPDATE -#endif +#endif // typedef boost::property VertexProperty; typedef boost::adjacency_list < @@ -136,12 +135,13 @@ struct DocumentP std::map objectMap; DocumentObject* activeObject; Transaction *activeUndoTransaction; - Transaction *activeTransaction; + Transaction *activeTransaction; ///< FIXME: has no effect (2015-09-01, Fat-Zer) int iTransactionMode; int iTransactionCount; std::map mTransactions; std::map vertexMap; bool rollback; + bool undoing; ///< document in the midle of undo or redo bool closable; bool keepTrailingDigits; int iUndoMode; @@ -157,6 +157,7 @@ struct DocumentP iTransactionMode = 0; iTransactionCount = 0; rollback = false; + undoing = false; closable = true; keepTrailingDigits = true; iUndoMode = 0; @@ -573,9 +574,10 @@ bool Document::undo(void) // redo d->activeUndoTransaction = new Transaction(); d->activeUndoTransaction->Name = mUndoTransactions.back()->Name; - + d->undoing = true; // applying the undo mUndoTransactions.back()->apply(*this,false); + d->undoing = false; // save the redo mRedoTransactions.push_back(d->activeUndoTransaction); @@ -604,7 +606,9 @@ bool Document::redo(void) d->activeUndoTransaction->Name = mRedoTransactions.back()->Name; // do the redo + d->undoing = true; mRedoTransactions.back()->apply(*this,true); + d->undoing = false; mUndoTransactions.push_back(d->activeUndoTransaction); d->activeUndoTransaction = 0; @@ -927,6 +931,10 @@ Document::Document(void) ADD_PROPERTY_TYPE(Id,(""),0,Prop_None,"ID of the document"); ADD_PROPERTY_TYPE(Uid,(id),0,Prop_ReadOnly,"UUID of the document"); + // license stuff + ADD_PROPERTY_TYPE(License,("CC-BY 3.0"),0,Prop_None,"License string of the Item"); + ADD_PROPERTY_TYPE(LicenseURL,("http://creativecommons.org/licenses/by/3.0/"),0,Prop_None,"URL to the license text/contract"); + // license stuff int licenseId = App::GetApplication().GetParameterGroupByPath ("User parameter:BaseApp/Preferences/Document")->GetInt("prefLicenseType",0); @@ -983,6 +991,10 @@ Document::Document(void) // this creates and sets 'TransientDir' in onChanged() ADD_PROPERTY_TYPE(TransientDir,(""),0,PropertyType(Prop_Transient|Prop_ReadOnly), "Transient directory, where the files live while the document is open"); + ADD_PROPERTY_TYPE(Tip,(0),0,PropertyType(Prop_Transient), + "Link of the tip object of the document"); + ADD_PROPERTY_TYPE(TipName,(""),0,PropertyType(Prop_Hidden|Prop_ReadOnly), + "Link of the tip object of the document"); Uid.touch(); } @@ -1103,7 +1115,7 @@ void Document::Restore(Base::XMLReader &reader) string name = reader.getAttribute("name"); try { - addObject(type.c_str(),name.c_str()); + addObject(type.c_str(), name.c_str(), /*isNew=*/ false); } catch ( Base::Exception& ) { Base::Console().Message("Cannot create object '%s'\n", name.c_str()); @@ -1130,6 +1142,10 @@ void Document::Restore(Base::XMLReader &reader) else if ( scheme >= 3 ) { // read the feature types readObjects(reader); + + // tip object handling. First the whole document has to be read, then we + // can restore the Tip link out of the TipName Property: + Tip.setValue(getObject(TipName.getValue())); } reader.readEndElement("Document"); @@ -1215,7 +1231,7 @@ Document::readObjects(Base::XMLReader& reader) // otherwise we may cause a dependency to itself // Example: Object 'Cut001' references object 'Cut' and removing the // digits we make an object 'Cut' referencing itself. - App::DocumentObject* obj = addObject(type.c_str(),name.c_str()); + App::DocumentObject* obj = addObject(type.c_str(), name.c_str(), /*isNew=*/ false); if (obj) { objs.push_back(obj); // use this name for the later access because an object with @@ -1336,6 +1352,11 @@ bool Document::save (void) compression = Base::clamp(compression, Z_NO_COMPRESSION, Z_BEST_COMPRESSION); if (*(FileName.getValue()) != '\0') { + // Save the name of the tip object in order to handle in Restore() + if(Tip.getValue()) { + TipName.setValue(Tip.getValue()->getNameInDocument()); + } + std::string LastModifiedDateString = Base::TimeInfo::currentDateTimeString(); LastModifiedDate.setValue(LastModifiedDateString.c_str()); // set author if needed @@ -1448,6 +1469,8 @@ void Document::restore (void) // !TODO mind exeptions while restoring! clearUndos(); for (std::vector::iterator obj = d->objectArray.begin(); obj != d->objectArray.end(); ++obj) { + // NOTE don't call unsetupObject () here due to it is intended to do some manipulations + // on other objects, but here we are wiping out document completely signalDeletedObject(*(*obj)); delete *obj; } @@ -1484,7 +1507,7 @@ void Document::restore (void) // without GUI. But if available then follow after all data files of the App document. signalRestoreDocument(reader); reader.readFiles(zipstream); - + // reset all touched for (std::map::iterator It= d->objectMap.begin();It!=d->objectMap.end();++It) { It->second->connectRelabelSignals(); @@ -1507,7 +1530,7 @@ bool Document::isSaved() const * matches with the file name where the document is stored to. * In contrast to Label the method getName() returns the internal name of the document that only * matches with Label when loading or creating a document because then both are set to the same value. - * Since the internal name cannot be changed during runtime it must differ from the Label after saving + * Since the internal name cannot be changed during runtime it must differ from the Label after saving * the document the first time or saving it under a new file name. * @ note More than one document can have the same label name. * @ note The internal is always guaranteed to be unique because @ref Application::newDocument() checks @@ -1604,7 +1627,7 @@ Document::getDependencyList(const std::vector& objs) const Vertex v = add_vertex(DepList); ObjectMap[*it] = v; VertexMap[v] = *it; - } + } for (std::vector::const_iterator it = d->objectArray.begin(); it != d->objectArray.end();++it) { std::vector outList = (*it)->getOutList(); @@ -1639,8 +1662,11 @@ Document::getDependencyList(const std::vector& objs) const // this sort gives the execute boost::topological_sort(DepList, std::front_inserter(make_order)); } - catch (const std::exception&) { - return std::vector(); + catch (const std::exception& e) { + std::stringstream ss; + ss << "Gathering all dependencies failed, probably due to circular dependencies. Error: "; + ss << e.what(); + throw Base::Exception(ss.str().c_str()); } std::set out; @@ -1751,7 +1777,7 @@ void Document::recompute() for (std::list::reverse_iterator i = make_order.rbegin();i != make_order.rend(); ++i) { DocumentObject* Cur = d->vertexMap[*i]; - if (!Cur) continue; + if (!Cur || !isIn(Cur)) continue; #ifdef FC_LOGFEATUREUPDATE std::clog << Cur->getNameInDocument() << " dep on:" ; #endif @@ -1816,7 +1842,7 @@ void Document::recompute() // reset all touched for (std::map::iterator it = d->vertexMap.begin(); it != d->vertexMap.end(); ++it) { - if (it->second) + if ((it->second) && isIn(it->second)) it->second->purgeTouched(); } d->vertexMap.clear(); @@ -1914,7 +1940,7 @@ void Document::recomputeFeature(DocumentObject* Feat) _recomputeFeature(Feat); } -DocumentObject * Document::addObject(const char* sType, const char* pObjectName) +DocumentObject * Document::addObject(const char* sType, const char* pObjectName, bool isNew) { Base::BaseClass* base = static_cast(Base::Type::createInstanceByName(sType,true)); @@ -1961,6 +1987,11 @@ DocumentObject * Document::addObject(const char* sType, const char* pObjectName) pcObject->Label.setValue( ObjectName ); + // Call the object-specific initialization + if (!d->undoing && !d->rollback && isNew) { + pcObject->setupObject (); + } + // mark the object as new (i.e. set status bit 2) and send the signal pcObject->StatusBits.set(2); signalNewObject(*pcObject); @@ -2050,7 +2081,14 @@ void Document::remObject(const char* sName) if (d->activeObject == pos->second) d->activeObject = 0; + // Mark the object as about to be deleted + pos->second->StatusBits.set (ObjectStatus::Delete); + if (!d->undoing && !d->rollback) { + pos->second->unsetupObject(); + } signalDeletedObject(*(pos->second)); + pos->second->StatusBits.reset (ObjectStatus::Delete); // Unset the bit to be on the safe side + if (!d->vertexMap.empty()) { // recompute of document is running for (std::map::iterator it = d->vertexMap.begin(); it != d->vertexMap.end(); ++it) { @@ -2064,6 +2102,12 @@ void Document::remObject(const char* sName) // Before deleting we must nullify all dependant objects breakDependency(pos->second, true); + //and remove the tip if needed + if(Tip.getValue() && strcmp(Tip.getValue()->getNameInDocument(), sName)==0) { + Tip.setValue(nullptr); + TipName.setValue(""); + } + // do no transactions if we do a rollback! if(!d->rollback){ @@ -2098,14 +2142,29 @@ void Document::remObject(const char* sName) /// Remove an object out of the document (internal) void Document::_remObject(DocumentObject* pcObject) { + // TODO Refactoring: share code with Document::remObject() (2015-09-01, Fat-Zer) _checkTransaction(pcObject); std::map::iterator pos = d->objectMap.find(pcObject->getNameInDocument()); + if (d->activeObject == pcObject) d->activeObject = 0; + // Mark the object as about to be deleted + pcObject->StatusBits.set (ObjectStatus::Delete); + if (!d->undoing && !d->rollback) { + pcObject->unsetupObject(); + } signalDeletedObject(*pcObject); + // TODO Check me if it's needed (2015-09-01, Fat-Zer) + pcObject->StatusBits.reset (ObjectStatus::Delete); // Unset the bit to be on the safe side + + //remove the tip if needed + if(Tip.getValue() == pcObject) { + Tip.setValue(nullptr); + TipName.setValue(""); + } // do no transactions if we do a rollback! if(!d->rollback){ @@ -2290,6 +2349,16 @@ DocumentObject * Document::getObject(const char *Name) const return 0; } +// Note: This method is only used in Tree.cpp slotChangeObject(), see explanation there +const bool Document::isIn(const DocumentObject *pFeat) const +{ + for (std::map::const_iterator o = d->objectMap.begin(); o != d->objectMap.end(); o++) + if (o->second == pFeat) + return true; + + return false; +} + const char * Document::getObjectName(DocumentObject *pFeat) const { std::map::const_iterator pos; diff --git a/src/App/Document.h b/src/App/Document.h index 1402f7cc4..c74948eb0 100644 --- a/src/App/Document.h +++ b/src/App/Document.h @@ -30,6 +30,7 @@ #include "PropertyContainer.h" #include "PropertyStandard.h" +#include "PropertyLinks.h" #include #include @@ -84,17 +85,21 @@ public: PropertyUUID Uid; /** License string * Holds the short license string for the Item, e.g. CC-BY - * for the Creative Commons license suit. + * for the Creative Commons license suit. */ App::PropertyString License; /// License descripton/contract URL App::PropertyString LicenseURL; /// Meta descriptons App::PropertyMap Meta; - /// Meta descriptons + /// Material descriptons, used and defined in the Material module. App::PropertyMap Material; /// read-only name of the temp dir created wen the document is opened - PropertyString TransientDir; + PropertyString TransientDir; + /// Tip object of the document (if any) + PropertyLink Tip; + /// Tip object of the document (if any) + PropertyString TipName; //@} /** @name Signals of the document */ @@ -116,7 +121,7 @@ public: boost::signal signalRedo; /** signal on load/save document * this signal is given when the document gets streamed. - * you can use this hook to write additional information in + * you can use this hook to write additional information in * the file (like the Gui::Document it does). */ boost::signal signalSaveDocument; @@ -162,9 +167,14 @@ public: /** @name Object handling */ //@{ /** Add a feature of sType with sName (ASCII) to this document and set it active. - * Unicode names are set through the Label property. + * Unicode names are set through the Label propery. + * @param sType the type of created object + * @param pObjectName if nonNULL use that name otherwise generate a new uniq name based on the \a sType + * @param isNew if false don't call the \c DocumentObject::setupObject() callback (default is true) */ - DocumentObject *addObject(const char* sType, const char* pObjectName=0); + DocumentObject *addObject(const char* sType, const char* pObjectName=0, bool isNew=true); + /// Remove a feature out of the document + void remObject(const char* sName); /** Add an existing feature with sName (ASCII) to this document and set it active. * Unicode names are set through the Label property. * This is an overloaded function of the function above and can be used to create @@ -173,8 +183,8 @@ public: * is raisedd. */ void addObject(DocumentObject*, const char* pObjectName=0); - /// Remove a feature out of the document - void remObject(const char* sName); + + /** Copy an object from another document to this document * If \a recursive is true then all objects this object depends on * are copied as well. By default \a recursive is false. @@ -192,6 +202,8 @@ public: DocumentObject *getActiveObject(void) const; /// Returns a Object of this document DocumentObject *getObject(const char *Name) const; + /// Returns true if the DocumentObject is contained in this document + const bool isIn(const DocumentObject *pFeat) const; /// Returns a Name of an Object or 0 const char *getObjectName(DocumentObject *pFeat) const; /// Returns a Name of an Object or 0 @@ -236,16 +248,16 @@ public: /** @name methods for the UNDO REDO and Transaction handling */ //@{ /// switch the level of Undo/Redo - void setUndoMode(int iMode); + void setUndoMode(int iMode); /// switch the level of Undo/Redo - int getUndoMode(void) const; + int getUndoMode(void) const; /// switch the tranaction mode void setTransactionMode(int iMode); /// Open a new command Undo/Redo, an UTF-8 name can be specified void openTransaction(const char* name=0); // Commit the Command transaction. Do nothing If there is no Command transaction open. void commitTransaction(); - /// Abort the actually running transaction. + /// Abort the actually running transaction. void abortTransaction(); /// Check if a transaction is open bool hasPendingTransaction() const; @@ -300,7 +312,7 @@ public: friend class Transaction; friend class TransactionObject; - /// Destruction + /// Destruction virtual ~Document(); protected: diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp index ca44ceb90..f4447ea06 100644 --- a/src/App/DocumentObject.cpp +++ b/src/App/DocumentObject.cpp @@ -59,7 +59,7 @@ DocumentObject::DocumentObject(void) DocumentObject::~DocumentObject(void) { if (!PythonObject.is(Py::_None())){ - // Remark: The API of Py::Object has been changed to set whether the wrapper owns the passed + // Remark: The API of Py::Object has been changed to set whether the wrapper owns the passed // Python object or not. In the constructor we forced the wrapper to own the object so we need // not to dec'ref the Python object any more. // But we must still invalidate the Python object because it need not to be @@ -115,7 +115,7 @@ const char* DocumentObject::getStatusString(void) const const char *DocumentObject::getNameInDocument(void) const { // Note: It can happen that we query the internal name of an object even if it is not - // part of a document (anymore). This is the case e.g. if we have a reference in Python + // part of a document (anymore). This is the case e.g. if we have a reference in Python // to an object that has been removed from the document. In this case we should rather // return 0. //assert(pcNameInDocument); @@ -172,6 +172,40 @@ DocumentObjectGroup* DocumentObject::getGroup() const return DocumentObjectGroup::getGroupOfObject(this); } +bool DocumentObject::testIfLinkDAGCompatible(DocumentObject *linkTo) const +{ + std::vector linkTo_in_vector; + linkTo_in_vector.push_back(linkTo); + return this->testIfLinkDAGCompatible(linkTo_in_vector); +} + +bool DocumentObject::testIfLinkDAGCompatible(const std::vector &linksTo) const +{ + Document* doc = this->getDocument(); + if (!doc) + throw Base::Exception("DocumentObject::testIfLinkIsDAG: object is not in any document."); + std::vector deplist = doc->getDependencyList(linksTo); + if( std::find(deplist.begin(),deplist.end(),this) != deplist.end() ) + //found this in dependency list + return false; + else + return true; +} + +bool DocumentObject::testIfLinkDAGCompatible(PropertyLinkSubList &linksTo) const +{ + const std::vector &linksTo_in_vector = linksTo.getValues(); + return this->testIfLinkDAGCompatible(linksTo_in_vector); +} + +bool DocumentObject::testIfLinkDAGCompatible(PropertyLinkSub &linkTo) const +{ + std::vector linkTo_in_vector; + linkTo_in_vector.reserve(1); + linkTo_in_vector.push_back(linkTo.getValue()); + return this->testIfLinkDAGCompatible(linkTo_in_vector); +} + void DocumentObject::onLostLinkToObject(DocumentObject*) { @@ -221,7 +255,7 @@ PyObject *DocumentObject::getPyObject(void) // ref counter is set to 1 PythonObject = Py::Object(new DocumentObjectPy(this),true); } - return Py::new_reference_to(PythonObject); + return Py::new_reference_to(PythonObject); } std::vector DocumentObject::getPySubObjects(const std::vector&) const diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index 8b32e7a5e..437b0dafd 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -47,6 +48,7 @@ enum ObjectStatus { New = 2, Recompute = 3, Restore = 4, + Delete = 5, Expand = 16 }; @@ -114,6 +116,8 @@ public: bool isRecomputing() const {return StatusBits.test(3);} /// returns true if this objects is currently restoring from file bool isRestoring() const {return StatusBits.test(4);} + /// returns true if this objects is currently restoring from file + bool isDeleting() const {return StatusBits.test(5);} /// recompute only this object virtual App::DocumentObjectExecReturn *recompute(void); /// return the status bits @@ -129,6 +133,21 @@ public: /// get group if object is part of a group, otherwise 0 is returned DocumentObjectGroup* getGroup() const; + /** + * @brief testIfLinkIsDAG tests a link that is about to be created for + * circular references. + * @param objToLinkIn (input). The object this object is to depend on after + * the link is going to be created. + * @return true if link can be created (no cycles will be made). False if + * the link will cause a circular dependency and break recomputes. Throws an + * error if the document already has a circular dependency. + * That is, if the return is true, the link is allowed. + */ + bool testIfLinkDAGCompatible(DocumentObject* linkTo) const; + bool testIfLinkDAGCompatible(const std::vector &linksTo) const; + bool testIfLinkDAGCompatible(App::PropertyLinkSubList &linksTo) const; + bool testIfLinkDAGCompatible(App::PropertyLinkSub &linkTo) const; + public: /** mustExecute @@ -194,7 +213,7 @@ protected: * 2 - object is marked as 'new' * 3 - object is marked as 'recompute', i.e. the object gets recomputed now * 4 - object is marked as 'restoring', i.e. the object gets loaded at the moment - * 5 - reserved + * 5 - object is marked as 'deleting', i.e. the object gets deleted at the moment * 6 - reserved * 7 - reserved * 16 - object is marked as 'expanded' in the tree view @@ -213,6 +232,10 @@ protected: virtual void onDocumentRestored() {} /// get called after setting the document virtual void onSettingDocument() {} + /// get called after a brand new object was created + virtual void setupObject() {} + /// get called when object is going to be removed from the document + virtual void unsetupObject() {} /// python object of this class and all descendend protected: // attributes diff --git a/src/App/DocumentObjectGroup.cpp b/src/App/DocumentObjectGroup.cpp index 6fb6ebbf9..474a00276 100644 --- a/src/App/DocumentObjectGroup.cpp +++ b/src/App/DocumentObjectGroup.cpp @@ -29,14 +29,14 @@ #include "DocumentObjectGroup.h" #include "DocumentObjectGroupPy.h" #include "Document.h" -#include "FeaturePythonPyImp.h" +#include "FeaturePythonPyImp.h" using namespace App; PROPERTY_SOURCE(App::DocumentObjectGroup, App::DocumentObject) -DocumentObjectGroup::DocumentObjectGroup() +DocumentObjectGroup::DocumentObjectGroup() { ADD_PROPERTY_TYPE(Group,(0),"Base",(App::PropertyType)(Prop_Output),"List of referenced objects"); } @@ -63,20 +63,22 @@ void DocumentObjectGroup::addObject(DocumentObject* obj) void DocumentObjectGroup::removeObject(DocumentObject* obj) { - std::vector grp = Group.getValues(); - for (std::vector::iterator it = grp.begin(); it != grp.end(); ++it) { - if (*it == obj) { - grp.erase(it); - Group.setValues(grp); - break; - } + const std::vector & grp = Group.getValues(); + std::vector newGrp; + + std::remove_copy (grp.begin(), grp.end(), std::back_inserter (newGrp), obj); + if (grp.size() != newGrp.size()) { + Group.setValues (newGrp); } } void DocumentObjectGroup::removeObjectsFromDocument() { - std::vector grp = Group.getValues(); - for (std::vector::iterator it = grp.begin(); it != grp.end(); ++it) { + const std::vector & grp = Group.getValues(); + // Use set so iterate on each linked object exactly one time (in case of multiple links to the same document) + std::set grpSet (grp.begin(), grp.end()); + + for (std::set::iterator it = grpSet.begin(); it != grpSet.end(); ++it) { removeObjectFromDocument(*it); } } @@ -85,11 +87,9 @@ void DocumentObjectGroup::removeObjectFromDocument(DocumentObject* obj) { // remove all children if (obj->getTypeId().isDerivedFrom(DocumentObjectGroup::getClassTypeId())) { - std::vector grp = static_cast(obj)->Group.getValues(); - for (std::vector::iterator it = grp.begin(); it != grp.end(); ++it) { - // recursive call to remove all subgroups - removeObjectFromDocument(*it); - } + DocumentObjectGroup *grp = static_cast(obj); + // recursive call to remove all subgroups + grp->removeObjectsFromDocument(); } this->getDocument()->remObject(obj->getNameInDocument()); @@ -103,12 +103,18 @@ DocumentObject *DocumentObjectGroup::getObject(const char *Name) const return 0; } -bool DocumentObjectGroup::hasObject(const DocumentObject* obj) const +bool DocumentObjectGroup::hasObject(const DocumentObject* obj, bool recursive) const { const std::vector& grp = Group.getValues(); for (std::vector::const_iterator it = grp.begin(); it != grp.end(); ++it) { - if (*it == obj) + if (*it == obj) { return true; + } else if ( recursive && (*it)->isDerivedFrom (App::DocumentObjectGroup::getTypeId()) ) { + App::DocumentObjectGroup *subGroup = static_cast (*it); + if (subGroup->hasObject (obj, recursive)) { + return true; + } + } } return false; @@ -162,7 +168,7 @@ DocumentObjectGroup* DocumentObjectGroup::getGroupOfObject(const DocumentObject* { const Document* doc = obj->getDocument(); std::vector grps = doc->getObjectsOfType(DocumentObjectGroup::getClassTypeId()); - for (std::vector::iterator it = grps.begin(); it != grps.end(); ++it) { + for (std::vector::const_iterator it = grps.begin(); it != grps.end(); ++it) { DocumentObjectGroup* grp = (DocumentObjectGroup*)(*it); if (grp->hasObject(obj)) return grp; @@ -177,7 +183,7 @@ PyObject *DocumentObjectGroup::getPyObject() // ref counter is set to 1 PythonObject = Py::Object(new DocumentObjectGroupPy(this),true); } - return Py::new_reference_to(PythonObject); + return Py::new_reference_to(PythonObject); } // Python feature --------------------------------------------------------- diff --git a/src/App/DocumentObjectGroup.h b/src/App/DocumentObjectGroup.h index 49330ed0a..b0a549a29 100644 --- a/src/App/DocumentObjectGroup.h +++ b/src/App/DocumentObjectGroup.h @@ -45,11 +45,11 @@ public: /** @name Object handling */ //@{ - /** Adds an object of \a sType with \a pObjectName to the document this group belongs to and + /** Adds an object of \a sType with \a pObjectName to the document this group belongs to and * append it to this group as well. */ DocumentObject *addObject(const char* sType, const char* pObjectName); - /* Adds the object \a obj to this group. + /* Adds the object \a obj to this group. */ void addObject(DocumentObject* obj); /** Removes an object from this group. @@ -64,8 +64,10 @@ public: DocumentObject *getObject(const char* Name) const; /** * Checks whether the object \a obj is part of this group. + * @param obj the object to check for. + * @param recursive if true check also if the obj is child of some sub group (default is false). */ - bool hasObject(const DocumentObject* obj) const; + bool hasObject(const DocumentObject* obj, bool recursive=false) const; /** * Checks whether this group object is a child (or sub-child) * of the given group object. diff --git a/src/App/DocumentObjectGroupPy.xml b/src/App/DocumentObjectGroupPy.xml index 8ceb8e58b..a39ee8c21 100644 --- a/src/App/DocumentObjectGroupPy.xml +++ b/src/App/DocumentObjectGroupPy.xml @@ -39,10 +39,14 @@ - - Checks if the group has a given object + + hasObject(obj, recursive=false) + Checks if the group has a given object + @param obj the object to check for. + @param recursive if true check also if the obj is child of some sub group (default is false). + - + diff --git a/src/App/DocumentObjectGroupPyImp.cpp b/src/App/DocumentObjectGroupPyImp.cpp index 222f59839..bb290ee44 100644 --- a/src/App/DocumentObjectGroupPyImp.cpp +++ b/src/App/DocumentObjectGroupPyImp.cpp @@ -48,7 +48,7 @@ PyObject* DocumentObjectGroupPy::newObject(PyObject *args) DocumentObject *object = getDocumentObjectGroupPtr()->addObject(sType, sName); if ( object ) { return object->getPyObject(); - } + } else { PyErr_Format(Base::BaseExceptionFreeCADError, "Cannot create object of type '%s'", sType); return NULL; @@ -58,8 +58,8 @@ PyObject* DocumentObjectGroupPy::newObject(PyObject *args) PyObject* DocumentObjectGroupPy::addObject(PyObject *args) { PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C + return NULL; // NULL triggers exception DocumentObjectPy* docObj = static_cast(object); if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->getNameInDocument()) { @@ -109,8 +109,8 @@ PyObject* DocumentObjectGroupPy::addObject(PyObject *args) PyObject* DocumentObjectGroupPy::removeObject(PyObject *args) { PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C + return NULL; // NULL triggers exception DocumentObjectPy* docObj = static_cast(object); if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->getNameInDocument()) { @@ -148,8 +148,8 @@ PyObject* DocumentObjectGroupPy::removeObject(PyObject *args) PyObject* DocumentObjectGroupPy::removeObjectsFromDocument(PyObject *args) { - if (!PyArg_ParseTuple(args, "")) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "")) // convert args: Python->C + return NULL; // NULL triggers exception getDocumentObjectGroupPtr()->removeObjectsFromDocument(); Py_Return; @@ -158,8 +158,8 @@ PyObject* DocumentObjectGroupPy::removeObjectsFromDocument(PyObject *args) PyObject* DocumentObjectGroupPy::getObject(PyObject *args) { char* pcName; - if (!PyArg_ParseTuple(args, "s", &pcName)) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "s", &pcName)) // convert args: Python->C + return NULL; // NULL triggers exception DocumentObject* obj = getDocumentObjectGroupPtr()->getObject(pcName); if ( obj ) { @@ -172,8 +172,10 @@ PyObject* DocumentObjectGroupPy::getObject(PyObject *args) PyObject* DocumentObjectGroupPy::hasObject(PyObject *args) { PyObject *object; - if (!PyArg_ParseTuple(args, "O!", &(DocumentObjectPy::Type), &object)) // convert args: Python->C - return NULL; // NULL triggers exception + PyObject *recursivePy = 0; + int recursive = 0; + if (!PyArg_ParseTuple(args, "O!|O", &(DocumentObjectPy::Type), &object, &recursivePy)) + return NULL; // NULL triggers exception DocumentObjectPy* docObj = static_cast(object); if (!docObj->getDocumentObjectPtr() || !docObj->getDocumentObjectPtr()->getNameInDocument()) { @@ -184,8 +186,16 @@ PyObject* DocumentObjectGroupPy::hasObject(PyObject *args) PyErr_SetString(Base::BaseExceptionFreeCADError, "Cannot check an object from another document with this group"); return NULL; } + if (recursivePy) { + recursive = PyObject_IsTrue(recursivePy); + if ( recursive == -1) { + // Note: shouldn't happen + PyErr_SetString(PyExc_ValueError, "The recursive parameter should be of boolean type"); + return 0; + } + } - bool v = getDocumentObjectGroupPtr()->hasObject(docObj->getDocumentObjectPtr()); + bool v = getDocumentObjectGroupPtr()->hasObject(docObj->getDocumentObjectPtr(), recursive); return PyBool_FromLong(v ? 1 : 0); } @@ -196,6 +206,6 @@ PyObject *DocumentObjectGroupPy::getCustomAttributes(const char* /*attr*/) const int DocumentObjectGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) { - return 0; + return 0; } diff --git a/src/App/GeoFeature.cpp b/src/App/GeoFeature.cpp index 053e0e2cf..cc55fe77d 100644 --- a/src/App/GeoFeature.cpp +++ b/src/App/GeoFeature.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2002 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -45,7 +45,7 @@ GeoFeature::GeoFeature(void) GeoFeature::~GeoFeature(void) { -} +} void GeoFeature::transformPlacement(const Base::Placement &transform) { diff --git a/src/App/GeoFeature.h b/src/App/GeoFeature.h index ba9f9d88d..f022ef63a 100644 --- a/src/App/GeoFeature.h +++ b/src/App/GeoFeature.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2002 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -46,10 +46,17 @@ public: GeoFeature(void); virtual ~GeoFeature(); + /** + * @brief transformPlacement applies transform to placement of this shape. + * Override this function to propagate the change of placement to base + * features, for example. By the time of writing this comment, the function + * was only called by alignment task (Edit->Alignment) + * @param transform (input). + */ virtual void transformPlacement(const Base::Placement &transform); }; } //namespace App -#endif // APP_GEOFEATURE_H +#endif // APP_GEOFEATURE_H diff --git a/src/App/GeoFeatureGroup.cpp b/src/App/GeoFeatureGroup.cpp new file mode 100644 index 000000000..4cbb6bb4e --- /dev/null +++ b/src/App/GeoFeatureGroup.cpp @@ -0,0 +1,175 @@ +/*************************************************************************** + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2014 * + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#endif + +#include + +#include "GeoFeatureGroup.h" +#include "GeoFeatureGroupPy.h" +#include "FeaturePythonPyImp.h" + +using namespace App; + + +PROPERTY_SOURCE(App::GeoFeatureGroup, App::DocumentObjectGroup) + + +//=========================================================================== +// Feature +//=========================================================================== + +GeoFeatureGroup::GeoFeatureGroup(void) +{ + ADD_PROPERTY(Placement,(Base::Placement())); +} + +GeoFeatureGroup::~GeoFeatureGroup(void) +{ +} + +void GeoFeatureGroup::transformPlacement(const Base::Placement &transform) +{ + // NOTE: Keep in sync with APP::GeoFeature + Base::Placement plm = this->Placement.getValue(); + plm = transform * plm; + this->Placement.setValue(plm); +} + +std::vector GeoFeatureGroup::getGeoSubObjects () const { + const auto & objs = Group.getValues(); + + std::set processedGroups; + std::set rvSet; + std::set curSearchSet (objs.begin(), objs.end()); + + processedGroups.insert ( this ); + + while ( !curSearchSet.empty() ) { + rvSet.insert ( curSearchSet.begin (), curSearchSet.end () ); + + std::set nextSearchSet; + for ( auto obj: curSearchSet) { + if ( isNonGeoGroup (obj) ) { + const App::DocumentObjectGroup *grp = static_cast (obj); + // Check if we havent already processed the element may happen in case of nontree structure + // Note: if the condition is false this generally indicates malformed structure + if ( processedGroups.find (grp) == processedGroups.end() ) { + processedGroups.insert ( grp ); + const auto & objs = grp->Group.getValues(); + nextSearchSet.insert (objs.begin(), objs.end()); + } + } + } + nextSearchSet.swap (curSearchSet); + } + + return std::vector ( rvSet.begin(), rvSet.end() ); +} + +bool GeoFeatureGroup::geoHasObject (const DocumentObject* obj) const { + const auto & objs = Group.getValues(); + + if (!obj) { + return false; + } + + std::set processedGroups; + std::set curSearchSet (objs.begin(), objs.end()); + + processedGroups.insert ( this ); + + while ( !curSearchSet.empty() ) { + if ( curSearchSet.find (obj) != curSearchSet.end() ) { + return true; + } + std::set nextSearchSet; + for ( auto obj: curSearchSet) { + if ( isNonGeoGroup (obj) ) { + const App::DocumentObjectGroup *grp = static_cast (obj); + if ( processedGroups.find (grp) == processedGroups.end() ) { + processedGroups.insert ( grp ); + const auto & objs = grp->Group.getValues(); + nextSearchSet.insert (objs.begin(), objs.end()); + } + } + } + nextSearchSet.swap (curSearchSet); + } + return false; +} + +GeoFeatureGroup* GeoFeatureGroup::getGroupOfObject(const DocumentObject* obj, bool indirect) +{ + const Document* doc = obj->getDocument(); + std::vector grps = doc->getObjectsOfType(GeoFeatureGroup::getClassTypeId()); + for (std::vector::const_iterator it = grps.begin(); it != grps.end(); ++it) { + GeoFeatureGroup* grp = (GeoFeatureGroup*)(*it); + if ( indirect ) { + if (grp->geoHasObject(obj)) { + return grp; + } + } else { + if (grp->hasObject(obj)) { + return grp; + } + } + } + + return 0; +} + +PyObject *GeoFeatureGroup::getPyObject() +{ + if (PythonObject.is(Py::_None())){ + // ref counter is set to 1 + PythonObject = Py::Object(new GeoFeatureGroupPy(this),true); + } + return Py::new_reference_to(PythonObject); +} + +// Python feature --------------------------------------------------------- + + +namespace App { +/// @cond DOXERR +PROPERTY_SOURCE_TEMPLATE(App::GeoFeatureGroupPython, App::GeoFeatureGroup) +template<> const char* App::GeoFeatureGroupPython::getViewProviderName(void) const { + return "Gui::ViewProviderGeoFeatureGroupPython"; +} +template<> PyObject* App::GeoFeatureGroupPython::getPyObject(void) { + if (PythonObject.is(Py::_None())) { + // ref counter is set to 1 + PythonObject = Py::Object(new FeaturePythonPyT(this),true); + } + return Py::new_reference_to(PythonObject); +} +/// @endcond + +// explicit template instantiation +template class AppExport FeaturePythonT; +} diff --git a/src/App/GeoFeatureGroup.h b/src/App/GeoFeatureGroup.h new file mode 100644 index 000000000..e3aed4c60 --- /dev/null +++ b/src/App/GeoFeatureGroup.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2014 * + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef APP_GeoFeatureGroup_H +#define APP_GeoFeatureGroup_H + +#include + +#include "DocumentObjectGroup.h" +#include "PropertyGeo.h" + +namespace App +{ + +/** + * The base class for placeable group of DocumentObjects + */ +class AppExport GeoFeatureGroup : public App::DocumentObjectGroup +{ + PROPERTY_HEADER(App::GeoFeatureGroup); + +public: + PropertyPlacement Placement; + + /** + * @brief transformPlacement applies transform to placement of this shape. + * Override this function to propagate the change of placement to base + * features. + * @param transform (input). + */ + virtual void transformPlacement(const Base::Placement &transform); + /// Constructor + GeoFeatureGroup(void); + virtual ~GeoFeatureGroup(); + + /// Returns all geometrically controlled objects: all objects of this group and it's non-geo subgroups + std::vector getGeoSubObjects () const; + + /// Returns true if either the group or one of it's non-geo subgroups has the object + bool geoHasObject (const DocumentObject* obj) const; + + /** Returns the geo feature group which contains this object. + * In case this object is not part of any geoFeatureGroup 0 is returned. + * Unlike DocumentObjectGroup::getGroupOfObject serches only for GeoFeatureGroups + * @param obj the object to search for + * @param indirect if true return if the group that so-called geoHas the object, @see geoHasObject() + * default is true + */ + static GeoFeatureGroup* getGroupOfObject(const DocumentObject* obj, bool indirect=true); + + /// Returns true if the given DocumentObject is DocumentObjectGroup but not GeoFeatureGroup + static bool isNonGeoGroup(const DocumentObject* obj) { + return obj->isDerivedFrom ( App::DocumentObjectGroup::getClassTypeId () ) && + !obj->isDerivedFrom ( App::GeoFeatureGroup::getClassTypeId () ); + } + + /// Returns the type name of the ViewProvider + virtual const char* getViewProviderName(void) const { + return "Gui::ViewProviderGeoFeatureGroup"; + } + + virtual PyObject *getPyObject(void); +}; + +typedef App::FeaturePythonT GeoFeatureGroupPython; + +} //namespace App + + +#endif // APP_GeoFeatureGroup_H diff --git a/src/App/GeoFeatureGroupPy.xml b/src/App/GeoFeatureGroupPy.xml new file mode 100644 index 000000000..a5ffdccec --- /dev/null +++ b/src/App/GeoFeatureGroupPy.xml @@ -0,0 +1,18 @@ + + + + + + This class handles placeable group of document objects + + + + diff --git a/src/App/GeoFeatureGroupPyImp.cpp b/src/App/GeoFeatureGroupPyImp.cpp new file mode 100644 index 000000000..7f222089d --- /dev/null +++ b/src/App/GeoFeatureGroupPyImp.cpp @@ -0,0 +1,29 @@ + +#include "PreCompiled.h" + +#include "App/GeoFeatureGroup.h" + +// inclusion of the generated files (generated out of GeoFeatureGroupPy.xml) +#include "GeoFeatureGroupPy.h" +#include "GeoFeatureGroupPy.cpp" + +using namespace App; + +// returns a string which represents the object e.g. when printed in python +std::string GeoFeatureGroupPy::representation(void) const +{ + return std::string(""); +} + + +PyObject *GeoFeatureGroupPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int GeoFeatureGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} + + diff --git a/src/App/GeoFeaturePy.xml b/src/App/GeoFeaturePy.xml new file mode 100644 index 000000000..5874da559 --- /dev/null +++ b/src/App/GeoFeaturePy.xml @@ -0,0 +1,23 @@ + + + + + + This class does the whole placement and position handling + + + + returns all posible paths to the root of the document + + + + + diff --git a/src/App/GeoFeaturePyImp.cpp b/src/App/GeoFeaturePyImp.cpp new file mode 100644 index 000000000..fbd3c0b11 --- /dev/null +++ b/src/App/GeoFeaturePyImp.cpp @@ -0,0 +1,40 @@ + +#include "PreCompiled.h" + +#include "App/GeoFeature.h" + +// inclusion of the generated files (generated out of GeoFeaturePy.xml) +#include "GeoFeaturePy.h" +#include "GeoFeaturePy.cpp" + +using namespace App; + +// returns a string which represents the object e.g. when printed in python +std::string GeoFeaturePy::representation(void) const +{ + return std::string(""); +} + + + +PyObject* GeoFeaturePy::getPaths(PyObject * /*args*/) +{ + PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented"); + return 0; +} + + + + + +PyObject *GeoFeaturePy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int GeoFeaturePy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} + + diff --git a/src/App/Origin.cpp b/src/App/Origin.cpp new file mode 100644 index 000000000..eafaf279e --- /dev/null +++ b/src/App/Origin.cpp @@ -0,0 +1,180 @@ +/*************************************************************************** + * Copyright (c) Stefan Tr�ger (stefantroeger@gmx.net) 2015 * + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#include +#endif + +#include +#include + +#include +#include "OriginFeature.h" + +#include "Origin.h" + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +using namespace App; + + +PROPERTY_SOURCE(App::Origin, App::DocumentObject) + +const char* Origin::AxisRoles[3] = {"X_Axis", "Y_Axis", "Z_Axis"}; +const char* Origin::PlaneRoles[3] = {"XY_Plane", "XZ_Plane", "YZ_Plane"}; + +Origin::Origin(void) { + ADD_PROPERTY_TYPE ( OriginFeatures, (0), 0, App::Prop_Hidden, + "Axis and baseplanes controlled by the origin" ); +} + + +Origin::~Origin(void) +{ } + +App::OriginFeature *Origin::getOriginFeature( const char *role) const { + const auto & features = OriginFeatures.getValues (); + auto featIt = std::find_if (features.begin(), features.end(), + [role] (App::DocumentObject *obj) { + return obj->isDerivedFrom ( App::OriginFeature::getClassTypeId () ) && + strcmp (static_cast(obj)->Role.getValue(), role) == 0; + } ); + if (featIt != features.end()) { + return static_cast(*featIt); + } else { + + std::stringstream err; + err << "Origin \"" << getNameInDocument () << "\" doesn't contain feature with role \"" + << role << '"'; + throw Base::Exception ( err.str().c_str () ); + } +} + +App::Line *Origin::getAxis( const char *role ) const { + App::OriginFeature *feat = getOriginFeature (role); + if ( feat->isDerivedFrom(App::Line::getClassTypeId () ) ) { + return static_cast (feat); + } else { + std::stringstream err; + err << "Origin \"" << getNameInDocument () << "\" contains bad Axis object for role \"" + << role << '"'; + throw Base::Exception ( err.str().c_str () ); + } +} + +App::Plane *Origin::getPlane( const char *role ) const { + App::OriginFeature *feat = getOriginFeature (role); + if ( feat->isDerivedFrom(App::Plane::getClassTypeId () ) ) { + return static_cast (feat); + } else { + std::stringstream err; + err << "Origin \"" << getNameInDocument () << "\" comtains bad Plane object for role \"" + << role << '"'; + throw Base::Exception ( err.str().c_str () ); + } +} + +bool Origin::hasObject (DocumentObject *obj) const { + const auto & features = OriginFeatures.getValues (); + return std::find (features.begin(), features.end(), obj) != features.end (); +} + +short Origin::mustExecute(void) const { + if (OriginFeatures.isTouched ()) { + return 1; + } else { + return DocumentObject::mustExecute(); + } +} + +App::DocumentObjectExecReturn *Origin::execute(void) { + try { // try to find all base axis and planes in the origin + for (const char* role: AxisRoles) { + App::Line *axis = getAxis (role); + assert(axis); + } + for (const char* role: PlaneRoles) { + App::Plane *plane = getPlane (role); + assert(plane); + } + } catch (const Base::Exception &ex) { + setError (); + return new App::DocumentObjectExecReturn ( ex.what () ); + } + + return DocumentObject::execute (); +} + +void Origin::setupObject () { + const static struct { + const Base::Type type; + const char *role; + Base::Rotation rot; + } setupData [] = { + {App::Line::getClassTypeId(), "X_Axis", Base::Rotation () }, + {App::Line::getClassTypeId(), "Y_Axis", Base::Rotation ( Base::Vector3d (1,1,1), M_PI*2/3 ) }, + {App::Line::getClassTypeId(), "Z_Axis", Base::Rotation ( Base::Vector3d (1,1,1), M_PI*4/3 ) }, + {App::Plane::getClassTypeId (), "XY_Plane", Base::Rotation () }, + {App::Plane::getClassTypeId (), "XZ_Plane", Base::Rotation ( Base::Vector3d (0,1,1), M_PI ), }, + {App::Plane::getClassTypeId (), "YZ_Plane", Base::Rotation ( Base::Vector3d (1,1,1), M_PI*2/3 ) }, + }; + + App::Document *doc = getDocument (); + + std::vector links; + for (auto data: setupData) { + std::string objName = doc->getUniqueObjectName ( data.role ); + App::DocumentObject *featureObj = doc->addObject ( data.type.getName(), objName.c_str () ); + + assert ( featureObj && featureObj->isDerivedFrom ( App::OriginFeature::getClassTypeId () ) ); + + App::OriginFeature *feature = static_cast ( featureObj ); + feature->Placement.setValue ( Base::Placement ( Base::Vector3d (), data.rot ) ); + feature->Role.setValue ( data.role ); + + links.push_back (feature); + } + + OriginFeatures.setValues (links); +} + +void Origin::unsetupObject () { + const auto &objsLnk = OriginFeatures.getValues (); + // Copy to set to assert we won't call methode more then one time for each object + std::set objs (objsLnk.begin(), objsLnk.end()); + // Remove all controlled objects + for (auto obj: objs ) { + // Check that previous deletes wasn't inderectly removed one of our objects + const auto &objsLnk = OriginFeatures.getValues (); + if ( std::find(objsLnk.begin(), objsLnk.end(), obj) != objsLnk.end()) { + if ( ! obj->isDeleting () ) { + obj->getDocument ()->remObject (obj->getNameInDocument()); + } + } + } +} diff --git a/src/App/Origin.h b/src/App/Origin.h new file mode 100644 index 000000000..451aef18a --- /dev/null +++ b/src/App/Origin.h @@ -0,0 +1,142 @@ +/*************************************************************************** + * Copyright (c) Stefan Tröger (stefantroeger@gmx.net) 2015 * + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef APP_Origin_H +#define APP_Origin_H + +#include "GeoFeature.h" + +#include "OriginFeature.h" +#include "PropertyLinks.h" + +namespace App +{ + +/** Base class of all geometric document objects. + */ +class AppExport Origin : public App::DocumentObject +{ + PROPERTY_HEADER(App::Origin); + +public: + /// Constructor + Origin(void); + virtual ~Origin(); + + /// returns the type name of the ViewProvider + virtual const char* getViewProviderName(void) const { + return "Gui::ViewProviderOrigin"; + } + + /** @name Axis and plane access + * This functions returns casted axis and planes objects and asserts they are setted correctly + * otherwice Base::Exception is thrown. + */ + ///@{ + // returns X axis + App::Line *getX () const { + return getAxis ("X_Axis"); + } + // returns Y axis + App::Line *getY () const { + return getAxis ("Y_Axis"); + } + // returns Z axis + App::Line *getZ () const { + return getAxis ("Z_Axis"); + } + + // returns XY plane + App::Plane *getXY () const { + return getPlane ("XY_Plane"); + } + // returns XZ plane + App::Plane *getXZ () const { + return getPlane ("XZ_Plane"); + } + // returns YZ plane + App::Plane *getYZ () const { + return getPlane ("YZ_Plane"); + } + + /// Returns all axis objects to iterate on them + std::vector axes() const { + return { getX(), getY(), getZ() }; + } + + /// Returns all base planes objects to iterate on them + std::vector planes() const { + return { getXY(), getXZ(), getYZ() }; + } + + /// Returns all controled objects (both planes and axis) to iterate on them + std::vector baseObjects() const { + return { getX(), getY(), getZ(), getXY(), getXZ(), getYZ() }; + } + + /// Returns an axis by it's name + App::OriginFeature *getOriginFeature( const char* role ) const; + + /// Returns an axis by it's name + App::Line *getAxis( const char* role ) const; + + /// Returns an axis by it's name + App::Plane *getPlane( const char* role ) const; + ///@} + + /// Returns true if the given object is part of the origin + bool hasObject (DocumentObject *obj) const; + + /// Returns the default bounding box of the origin (use this if you confused what should be s ) + // TODO Delete me if not really needed (2015-09-01, Fat-Zer) + static Base::BoundBox3d defaultBoundBox(); + + /// Returns true on changing OriginFeature set + virtual short mustExecute(void) const; + + /// Axis types + static const char* AxisRoles[3]; + /// Baseplane types + static const char* PlaneRoles[3]; + + // Axis links + PropertyLinkList OriginFeatures; + +protected: + /// Checks integrity of the Origin + virtual App::DocumentObjectExecReturn *execute(void); + /// Creates all corresponding Axises and Planes objects for the origin if they not linked yet + virtual void setupObject (); + /// Removes all planes and axis if they are still linked to the document + virtual void unsetupObject (); + +private: + struct SetupData; + void setupOriginFeature (App::PropertyLink &featProp, const SetupData &data); + +}; + +} //namespace App + +#endif // APP_Origin_H diff --git a/src/App/OriginFeature.cpp b/src/App/OriginFeature.cpp new file mode 100644 index 000000000..7bfb92b2f --- /dev/null +++ b/src/App/OriginFeature.cpp @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#endif + +#include "Document.h" +#include "Origin.h" + +#include "OriginFeature.h" + +using namespace App; + +PROPERTY_SOURCE(App::OriginFeature, App::GeoFeature) +PROPERTY_SOURCE(App::Plane, App::OriginFeature) +PROPERTY_SOURCE(App::Line, App::OriginFeature) + +OriginFeature::OriginFeature() +{ + ADD_PROPERTY_TYPE ( Role, (""), 0, App::Prop_ReadOnly, "Role of the feature in the Origin" ) ; + + // Set placement to read-only + Placement.setStatus(Property::Hidden, true); +} + +OriginFeature::~OriginFeature() +{ } + +Origin * OriginFeature::getOrigin () { + App::Document *doc = getDocument(); + auto origins = doc->getObjectsOfType ( App::Origin::getClassTypeId() ); + + auto originIt= std::find_if (origins.begin(), origins.end(), [this] (DocumentObject *origin) { + assert ( origin->isDerivedFrom ( App::Origin::getClassTypeId() ) ); + return static_cast (origin)->hasObject (this); + } ); + if (originIt == origins.end()) { + return 0; + } else { + assert ( (*originIt)->isDerivedFrom ( App::Origin::getClassTypeId() ) ); + return static_cast (*originIt); + } +} diff --git a/src/App/OriginFeature.h b/src/App/OriginFeature.h new file mode 100644 index 000000000..9858f2d50 --- /dev/null +++ b/src/App/OriginFeature.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2012 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef ORIGINFEATURE_H_6ZWJPB5V +#define ORIGINFEATURE_H_6ZWJPB5V + +#include "GeoFeature.h" + +namespace App +{ + +class Origin; + +/** Plane Object + * Used to define planar support for all kind of operations in the document space + */ +class AppExport OriginFeature: public App::GeoFeature +{ + PROPERTY_HEADER(App::OriginFeature); +public: + /// additional information about the feature usage (e.g. "BasePlane-XY" or "Axis-X" in a Origin) + PropertyString Role; + + /// Constructor + OriginFeature(void); + virtual ~OriginFeature(); + + /// Finds the origin object this plane belongs to + App::Origin *getOrigin (); +}; + +class AppExport Plane: public App::OriginFeature { + PROPERTY_HEADER(App::OriginFeature); +public: + virtual const char* getViewProviderName(void) const { + return "Gui::ViewProviderPlane"; + } +}; + +class AppExport Line: public App::OriginFeature { + PROPERTY_HEADER(App::OriginFeature); +public: + virtual const char* getViewProviderName(void) const { + return "Gui::ViewProviderLine"; + } +}; + +} //namespace App + +#endif /* end of include guard: ORIGINFEATURE_H_6ZWJPB5V */ diff --git a/src/App/OriginGroup.cpp b/src/App/OriginGroup.cpp new file mode 100644 index 000000000..8270708e7 --- /dev/null +++ b/src/App/OriginGroup.cpp @@ -0,0 +1,123 @@ +/*************************************************************************** + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#include "OriginGroup.h" + +#ifndef _PreComp_ +#endif + +#include + +#include +#include "Origin.h" + +#include "GeoFeature.h" + +using namespace App; + +PROPERTY_SOURCE(App::OriginGroup, App::GeoFeatureGroup); + +OriginGroup::OriginGroup () { + ADD_PROPERTY_TYPE ( Origin, (0), 0, App::Prop_Hidden, "Origin linked to the group" ); +} + +OriginGroup::~OriginGroup () +{ } + +App::Origin *OriginGroup::getOrigin () const { + App::DocumentObject *originObj = Origin.getValue (); + + if ( !originObj ) { + std::stringstream err; + err << "Can't find Origin for \"" << getNameInDocument () << "\""; + throw Base::Exception ( err.str().c_str () ); + + } else if (! originObj->isDerivedFrom ( App::Origin::getClassTypeId() ) ) { + std::stringstream err; + err << "Bad object \"" << originObj->getNameInDocument () << "\"(" << originObj->getTypeId().getName() + << ") linked to the Origin of \"" << getNameInDocument () << "\""; + throw Base::Exception ( err.str().c_str () ); + } else { + return static_cast ( originObj ); + } +} + +App::OriginGroup *OriginGroup::getGroupOfObject (const DocumentObject* obj, bool indirect) { + const Document* doc = obj->getDocument(); + std::vector grps = doc->getObjectsOfType ( OriginGroup::getClassTypeId() ); + for (auto grpObj: grps) { + OriginGroup* grp = static_cast (grpObj); + if ( indirect ) { + if ( grp->geoHasObject (obj) ) { + return grp; + } + } else { + if ( grp->hasObject (obj) ) { + return grp; + } + } + } + + return 0; +} + +short OriginGroup::mustExecute() const { + if (Origin.isTouched ()) { + return 1; + } else { + return GeoFeatureGroup::mustExecute(); + } +} + +App::DocumentObjectExecReturn *OriginGroup::execute() { + try { // try to find all base axis and planes in the origin + getOrigin (); + } catch (const Base::Exception &ex) { + setError (); + return new App::DocumentObjectExecReturn ( ex.what () ); + } + + return GeoFeatureGroup::execute (); +} + +void OriginGroup::setupObject () { + App::Document *doc = getDocument (); + + std::string objName = std::string ( getNameInDocument()).append ( "Origin" ); + + App::DocumentObject *originObj = doc->addObject ( "App::Origin", objName.c_str () ); + + assert ( originObj && originObj->isDerivedFrom ( App::Origin::getClassTypeId () ) ); + Origin.setValue (originObj); + + GeoFeatureGroup::setupObject (); +} + +void OriginGroup::unsetupObject () { + App::DocumentObject *origin = Origin.getValue (); + if (origin && !origin->isDeleting ()) { + origin->getDocument ()->remObject (origin->getNameInDocument()); + } + + GeoFeatureGroup::unsetupObject (); +} diff --git a/src/App/OriginGroup.h b/src/App/OriginGroup.h new file mode 100644 index 000000000..298715d30 --- /dev/null +++ b/src/App/OriginGroup.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef ORIGINGROUP_H_QHTU73IF +#define ORIGINGROUP_H_QHTU73IF + +#include "GeoFeatureGroup.h" +#include "PropertyLinks.h" + +namespace App { +class Origin; + +/** + * Represents an abstact placeable group of objects with an associated Origin + */ +class AppExport OriginGroup: public App::GeoFeatureGroup +{ + PROPERTY_HEADER(App::OriginGroup); +public: + OriginGroup (); + virtual ~OriginGroup (); + + /// Returns the origin link or throws an exception + App::Origin *getOrigin () const; + + /// returns the type name of the ViewProvider + virtual const char* getViewProviderName () const { + return "Gui::ViewProviderOriginGroup"; + } + + /** + * Returns the origin group which contains this object. + * In case this object is not part of any geoFeatureGroup 0 is returned. + * @param obj the object to search for + * @param indirect if true return if the group that so-called geoHas the object, @see geoHasObject() + * default is true + */ + static OriginGroup* getGroupOfObject (const DocumentObject* obj, bool indirect=true); + + /// Returns true on changing OriginFeature set + virtual short mustExecute () const; + + /// Origin linked to the group + PropertyLink Origin; + +protected: + /// Checks integrity of the Origin + virtual App::DocumentObjectExecReturn *execute (); + /// Creates the corresponding Origin object + virtual void setupObject (); + /// Removes all planes and axis if they are still linked to the document + virtual void unsetupObject (); +}; + +} /* App */ + +#endif /* end of include guard: ORIGINGROUP_H_QHTU73IF */ diff --git a/src/App/OriginGroupPy.xml b/src/App/OriginGroupPy.xml new file mode 100644 index 000000000..f85670446 --- /dev/null +++ b/src/App/OriginGroupPy.xml @@ -0,0 +1,19 @@ + + + + + + This class handles placable group of document objects with an Origin + + + + + diff --git a/src/App/OriginGroupPyImp.cpp b/src/App/OriginGroupPyImp.cpp new file mode 100644 index 000000000..78757021b --- /dev/null +++ b/src/App/OriginGroupPyImp.cpp @@ -0,0 +1,34 @@ + +#include "PreCompiled.h" + +#include "App/OriginGroup.h" + +// inclusion of the generated files (generated out of OriginGroupPy.xml) +#include "OriginGroupPy.h" +#include "OriginGroupPy.cpp" + +using namespace App; + +// returns a string which represents the object e.g. when printed in python +std::string OriginGroupPy::representation(void) const +{ + return std::string(""); +} + + + + + + + +PyObject *OriginGroupPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int OriginGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} + + diff --git a/src/App/Part.cpp b/src/App/Part.cpp new file mode 100644 index 000000000..bea977748 --- /dev/null +++ b/src/App/Part.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2014 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#endif + +#include + +#include "Part.h" +#include "PartPy.h" + + +using namespace App; + + +PROPERTY_SOURCE(App::Part, App::OriginGroup) + + +//=========================================================================== +// Part +//=========================================================================== + + +Part::Part(void) +{ + ADD_PROPERTY(Type,("")); + ADD_PROPERTY_TYPE(Material, (), 0, App::Prop_None, "Map with material properties"); + ADD_PROPERTY_TYPE(Meta, (), 0, App::Prop_None, "Map with additional meta information"); + + // create the uuid for the document + Base::Uuid id; + ADD_PROPERTY_TYPE(Id, (""), 0, App::Prop_None, "ID (Part-Number) of the Item"); + ADD_PROPERTY_TYPE(Uid, (id), 0, App::Prop_None, "UUID of the Item"); + + // license stuff + ADD_PROPERTY_TYPE(License, ("CC BY 3.0"), 0, App::Prop_None, "License string of the Item"); + ADD_PROPERTY_TYPE(LicenseURL, ("http://creativecommons.org/licenses/by/3.0/"), 0, App::Prop_None, "URL to the license text/contract"); + // color and apperance + ADD_PROPERTY(Color, (1.0, 1.0, 1.0, 1.0)); // set transparent -> not used + +} + +Part::~Part(void) +{ +} + +App::Part *Part::getPartOfObject (const DocumentObject* obj, bool indirect) { + const Document* doc = obj->getDocument(); + std::vector grps = doc->getObjectsOfType ( Part::getClassTypeId() ); + + for (auto partObj: grps) { + Part* part = static_cast (partObj); + if ( indirect ) { + if ( part->geoHasObject (obj) ) { + return part; + } + } else { + if ( part->hasObject (obj) ) { + return part; + } + } + } + + return 0; +} + + +PyObject *Part::getPyObject() +{ + if (PythonObject.is(Py::_None())){ + // ref counter is set to 1 + PythonObject = Py::Object(new PartPy(this),true); + } + return Py::new_reference_to(PythonObject); +} + +// Python feature --------------------------------------------------------- + +// Not quit sure yet makeing Part derivable in Python is good Idea! +// JR 2014 + +//namespace App { +///// @cond DOXERR +//PROPERTY_SOURCE_TEMPLATE(App::PartPython, App::Part) +//template<> const char* App::PartPython::getViewProviderName(void) const { +// return "Gui::ViewProviderPartPython"; +//} +//template<> PyObject* App::PartPython::getPyObject(void) { +// if (PythonObject.is(Py::_None())) { +// // ref counter is set to 1 +// PythonObject = Py::Object(new FeaturePythonPyT(this),true); +// } +// return Py::new_reference_to(PythonObject); +//} +///// @endcond +// +//// explicit template instantiation +//template class AppExport FeaturePythonT; +//} diff --git a/src/App/Part.h b/src/App/Part.h new file mode 100644 index 000000000..4de2806f9 --- /dev/null +++ b/src/App/Part.h @@ -0,0 +1,104 @@ +/*************************************************************************** + * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2014 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef APP_Part_H +#define APP_Part_H + +#include "OriginGroup.h" +#include "PropertyLinks.h" + + + +namespace App +{ + + +/** Base class of all geometric document objects. + */ +class AppExport Part : public App::OriginGroup +{ + PROPERTY_HEADER(App::Part); + +public: + /// type of the part + PropertyString Type; + + /** @name base properties of all Assembly Items + * This properties corospond mostly to the meta information + * in the App::Document class + */ + //@{ + /// Id e.g. Part number + App::PropertyString Id; + /// unique identifier of the Item + App::PropertyUUID Uid; + /// material descriptons + App::PropertyMap Material; + /// Meta descriptons + App::PropertyMap Meta; + + /** License string + * Holds the short license string for the Item, e.g. CC-BY + * for the Creative Commons license suit. + */ + App::PropertyString License; + /// License descripton/contract URL + App::PropertyString LicenseURL; + //@} + + /** @name Visual properties */ + //@{ + /** Base color of the Item + If the transparency value is 1.0 + the color or the next hirachy is used + */ + App::PropertyColor Color; + //@} + + /// Constructor + Part(void); + virtual ~Part(); + + /// returns the type name of the ViewProvider + virtual const char* getViewProviderName(void) const { + return "Gui::ViewProviderPart"; + } + + /** + * Returns the part which contains this object. + * In case this object is not belongs to any Part 0 is returned. + * @param obj the object to search for + * @param indirect if true return if the part that so-called geoHas the object, @see geoHasObject() + * default is true + */ + static App::Part* getPartOfObject (const DocumentObject* obj, bool indirect=true); + + virtual PyObject *getPyObject(void); +}; + +//typedef App::FeaturePythonT PartPython; + +} //namespace App + + +#endif // APP_Part_H diff --git a/src/App/PartPy.xml b/src/App/PartPy.xml new file mode 100644 index 000000000..fd1e2c957 --- /dev/null +++ b/src/App/PartPy.xml @@ -0,0 +1,19 @@ + + + + + + This class handles document objects in Part + + + + + diff --git a/src/App/PartPyImp.cpp b/src/App/PartPyImp.cpp new file mode 100644 index 000000000..347556199 --- /dev/null +++ b/src/App/PartPyImp.cpp @@ -0,0 +1,33 @@ + +#include "PreCompiled.h" + +#include "App/Part.h" + +// inclusion of the generated files (generated out of PartPy.xml) +#include "PartPy.h" +#include "PartPy.cpp" + +using namespace App; + +// returns a string which represents the object e.g. when printed in python +std::string PartPy::representation(void) const +{ + return std::string(""); +} + + + + + + +PyObject *PartPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int PartPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} + + diff --git a/src/App/Plane.cpp b/src/App/Path.cpp similarity index 81% rename from src/App/Plane.cpp rename to src/App/Path.cpp index 4e4ba42b5..5126fdfb8 100644 --- a/src/App/Plane.cpp +++ b/src/App/Path.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2012 * + * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2014 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -26,31 +26,21 @@ #ifndef _PreComp_ #endif - -#include "Plane.h" - +#include "Path.h" +#define new DEBUG_CLIENTBLOCK using namespace App; -PROPERTY_SOURCE(App::Plane, App::GeoFeature) - - -//=========================================================================== -// Feature -//=========================================================================== - -Plane::Plane(void) -{ - -} - -Plane::~Plane(void) +Path::Path(void) { } +Path::Path(const std::vector &PathVector) +:_PathVector(PathVector) +{ +} - - - - +Path::~Path(void) +{ +} diff --git a/src/App/Plane.h b/src/App/Path.h similarity index 74% rename from src/App/Plane.h rename to src/App/Path.h index 33a1d5e7f..772415828 100644 --- a/src/App/Plane.h +++ b/src/App/Path.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2012 * + * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2014 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -21,14 +21,10 @@ ***************************************************************************/ +#ifndef APP_Path_H +#define APP_Path_H - -#ifndef _AppPlane_h_ -#define _AppPlane_h_ - - -#include "GeoFeature.h" -#include "PropertyGeo.h" +#include @@ -36,28 +32,25 @@ namespace App { -/** Plane Object - * Used to define planar support for all kind of operations in the document space +/** Base class of all geometric document objects. */ -class AppExport Plane: public App::GeoFeature +class AppExport Path { - PROPERTY_HEADER(App::Plane); +protected: + std::vector _PathVector; public: + /// Constructor + Path(void); + Path(const std::vector & PathVector); - /// Constructor - Plane(void); - virtual ~Plane(); + virtual ~Path(); + + const std::vector & getVector(void)const{return _PathVector;} - /// returns the type name of the ViewProvider - virtual const char* getViewProviderName(void) const { - return "Gui::ViewProviderPlane"; - } }; - } //namespace App - -#endif +#endif // APP_Path_H diff --git a/src/App/PropertyLinks.cpp b/src/App/PropertyLinks.cpp index b366faea7..5e00cdbb3 100644 --- a/src/App/PropertyLinks.cpp +++ b/src/App/PropertyLinks.cpp @@ -249,7 +249,9 @@ void PropertyLinkSub::setPyObject(PyObject *value) } else if (PyTuple_Check(value) || PyList_Check(value)) { Py::Sequence seq(value); - if (PyObject_TypeCheck(seq[0].ptr(), &(DocumentObjectPy::Type))){ + if(seq.size() == 0) + setValue(NULL); + else if (PyObject_TypeCheck(seq[0].ptr(), &(DocumentObjectPy::Type))){ DocumentObjectPy *pcObj = (DocumentObjectPy*)seq[0].ptr(); if (seq[1].isString()) { std::vector vals; @@ -547,11 +549,18 @@ void PropertyLinkSubList::setValue(DocumentObject* lValue,const char* SubName) _lSubList.resize(1); _lSubList[0]=SubName; hasSetValue(); + } else { + aboutToSetValue(); + _lValueList.clear(); + _lSubList.clear(); + hasSetValue(); } } void PropertyLinkSubList::setValues(const std::vector& lValue,const std::vector& lSubNames) { + if (lValue.size() != lSubNames.size()) + throw Base::Exception("PropertyLinkSubList::setValues: size of subelements list != size of objects list"); aboutToSetValue(); _lValueList = lValue; _lSubList.resize(lSubNames.size()); @@ -563,12 +572,71 @@ void PropertyLinkSubList::setValues(const std::vector& lValue,c void PropertyLinkSubList::setValues(const std::vector& lValue,const std::vector& lSubNames) { + if (lValue.size() != lSubNames.size()) + throw Base::Exception("PropertyLinkSubList::setValues: size of subelements list != size of objects list"); aboutToSetValue(); _lValueList = lValue; _lSubList = lSubNames; hasSetValue(); } +void PropertyLinkSubList::setValue(DocumentObject* lValue, const std::vector &SubList) +{ + aboutToSetValue(); + int size = SubList.size(); + this->_lValueList.clear(); + if (size == 0) { + if (lValue) + this->_lValueList.push_back(lValue); + this->_lSubList.clear(); + } else { + this->_lSubList = SubList; + this->_lValueList.insert(this->_lValueList.begin(), size, lValue); + } + hasSetValue(); +} + +const string PropertyLinkSubList::getPyReprString() +{ + assert(this->_lValueList.size() == this->_lSubList.size()); + + if (this->_lValueList.size() == 0) + return std::string("None"); + + std::stringstream strm; + strm << "["; + for ( int i = 0 ; i < this->_lSubList.size() ; i++) { + if (i>0) + strm << ",("; + else + strm << "("; + App::DocumentObject* obj = this->_lValueList[i]; + if (obj) { + strm << "App.getDocument('" << obj->getDocument()->getName() << "')." << obj->getNameInDocument(); + } else { + strm << "None"; + } + strm << ","; + strm << "'" << this->_lSubList[i] << "'"; + strm << ")"; + } + strm << "]"; + return strm.str(); +} + +DocumentObject *PropertyLinkSubList::getValue() const +{ + App::DocumentObject* ret = 0; + //FIXME: cache this to avoid iterating each time, to improve speed + for (int i = 0 ; i < this->_lValueList.size() ; i++){ + if (ret == 0) + ret = this->_lValueList[i]; + if (ret != this->_lValueList[i]) + return 0; + } + return ret; +} + PyObject *PropertyLinkSubList::getPyObject(void) { unsigned int count = getSize(); @@ -591,44 +659,50 @@ PyObject *PropertyLinkSubList::getPyObject(void) void PropertyLinkSubList::setPyObject(PyObject *value) { - if (PyTuple_Check(value) || PyList_Check(value)) { - Py::Sequence list(value); - Py::Sequence::size_type size = list.size(); + try { //try PropertyLinkSub syntax + PropertyLinkSub dummy; + dummy.setPyObject(value); + this->setValue(dummy.getValue(), dummy.getSubValues()); + } catch (Base::TypeError) { - std::vector values; - values.reserve(size); - std::vector SubNames; - SubNames.reserve(size); + if (PyTuple_Check(value) || PyList_Check(value)) { + Py::Sequence list(value); + Py::Sequence::size_type size = list.size(); - for (Py::Sequence::size_type i=0; i(tup[0].ptr()); - values.push_back(pcObj->getDocumentObjectPtr()); - if (Py::Object(tup[1].ptr()).isString()){ - SubNames.push_back(Py::String(tup[1].ptr())); + std::vector values; + values.reserve(size); + std::vector SubNames; + SubNames.reserve(size); + for (Py::Sequence::size_type i=0; i(tup[0].ptr()); + values.push_back(pcObj->getDocumentObjectPtr()); + if (Py::Object(tup[1].ptr()).isString()){ + SubNames.push_back(Py::String(tup[1].ptr())); + } } } + else if (PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) { + DocumentObjectPy *pcObj; + pcObj = static_cast(*item); + values.push_back(pcObj->getDocumentObjectPtr()); + } + else if (item.isString()) { + SubNames.push_back(Py::String(item)); + } } - else if (PyObject_TypeCheck(*item, &(DocumentObjectPy::Type))) { - DocumentObjectPy *pcObj; - pcObj = static_cast(*item); - values.push_back(pcObj->getDocumentObjectPtr()); - } - else if (item.isString()) { - SubNames.push_back(Py::String(item)); - } - } - setValues(values,SubNames); - } - else { - std::string error = std::string("type must be 'DocumentObject' or list of 'DocumentObject', not "); - error += value->ob_type->tp_name; - throw Base::TypeError(error); + setValues(values,SubNames); + } + else { + std::string error = std::string("type must be 'DocumentObject' or list of 'DocumentObject', not "); + error += value->ob_type->tp_name; + throw Base::TypeError(error); + } } } @@ -683,6 +757,44 @@ void PropertyLinkSubList::Restore(Base::XMLReader &reader) setValues(values,SubNames); } +void PropertyLinkSubList::Restore_FromLinkSub(XMLReader &reader) +{ + //Copy-paste from PropertyLinkSub::Restore() + // read my element + reader.readElement("LinkSub"); + // get the values of my attributes + std::string name = reader.getAttribute("value"); + int count = reader.getAttributeAsInteger("count"); + + // Property not in a DocumentObject! + assert(getContainer()->getTypeId().isDerivedFrom(App::DocumentObject::getClassTypeId()) ); + + std::vector values(count); + for (int i = 0; i < count; i++) { + reader.readElement("Sub"); + values[i] = reader.getAttribute("value"); + } + + reader.readEndElement("LinkSub"); + + DocumentObject *pcObject; + if (name != ""){ + App::Document* document = static_cast(getContainer())->getDocument(); + pcObject = document ? document->getObject(name.c_str()) : 0; + if (!pcObject) { + if (reader.isVerbose()) { + Base::Console().Warning("Lost link to '%s' while loading, maybe " + "an object was not loaded correctly\n",name.c_str()); + } + } + setValue(pcObject,values); + } + else { + setValue(0); + } + +} + Property *PropertyLinkSubList::Copy(void) const { PropertyLinkSubList *p = new PropertyLinkSubList(); diff --git a/src/App/PropertyLinks.h b/src/App/PropertyLinks.h index 98d3adccd..87d3c1217 100644 --- a/src/App/PropertyLinks.h +++ b/src/App/PropertyLinks.h @@ -247,12 +247,19 @@ public: virtual void setSize(int newSize); virtual int getSize(void) const; - /** Sets the property + /** Sets the property. + * setValue(0, whatever) clears the property */ void setValue(DocumentObject*,const char*); void setValues(const std::vector&,const std::vector&); void setValues(const std::vector&,const std::vector&); + /** + * @brief setValue: PropertyLinkSub-compatible overload + * @param SubList + */ + void setValue(App::DocumentObject *lValue, const std::vector &SubList=std::vector()); + // index operator SubSet operator[] (const int idx) const { return SubSet(_lValueList.operator[] (idx),_lSubList.operator [](idx)); @@ -262,6 +269,16 @@ public: return _lValueList; } + const std::string getPyReprString(); + + /** + * @brief getValue emulates the action of a single-object link. + * @return reference to object, if the link os to only one object. NULL if + * the link is empty, or links to subelements of more than one documant + * object. + */ + DocumentObject* getValue() const; + const std::vector &getSubValues(void) const { return _lSubList; } @@ -271,6 +288,7 @@ public: virtual void Save (Base::Writer &writer) const; virtual void Restore(Base::XMLReader &reader); + virtual void Restore_FromLinkSub(Base::XMLReader &reader); virtual Property *Copy(void) const; virtual void Paste(const Property &from); diff --git a/src/Base/Exception.h b/src/Base/Exception.h index f17fa71cb..a4995b082 100644 --- a/src/Base/Exception.h +++ b/src/Base/Exception.h @@ -27,6 +27,7 @@ #define BASE_EXCEPTION_H #include +#include #include #include #include "FileInfo.h" diff --git a/src/Base/Reader.cpp b/src/Base/Reader.cpp index 61ff60649..b5c8fc112 100644 --- a/src/Base/Reader.cpp +++ b/src/Base/Reader.cpp @@ -393,15 +393,15 @@ bool Base::XMLReader::doNameMapping() const // --------------------------------------------------------------------------- // Base::XMLReader: Implementation of the SAX DocumentHandler interface // --------------------------------------------------------------------------- -void Base::XMLReader::startDocument() -{ - ReadType = StartDocument; -} - -void Base::XMLReader::endDocument() -{ - ReadType = EndDocument; -} +void Base::XMLReader::startDocument() +{ + ReadType = StartDocument; +} + +void Base::XMLReader::endDocument() +{ + ReadType = EndDocument; +} void Base::XMLReader::startElement(const XMLCh* const /*uri*/, const XMLCh* const localname, const XMLCh* const /*qname*/, const XERCES_CPP_NAMESPACE_QUALIFIER Attributes& attrs) { diff --git a/src/Base/RotationPyImp.cpp b/src/Base/RotationPyImp.cpp index d9bc2f9ce..d5d9687f9 100644 --- a/src/Base/RotationPyImp.cpp +++ b/src/Base/RotationPyImp.cpp @@ -77,9 +77,16 @@ int RotationPy::PyInit(PyObject* args, PyObject* /*kwd*/) PyErr_Clear(); double angle; if (PyArg_ParseTuple(args, "O!d", &(Base::VectorPy::Type), &o, &angle)) { - // NOTE: The last parameter defines the rotation angle in degree. - getRotationPtr()->setValue(static_cast(o)->value(), Base::toRadians(angle)); - return 0; + // NOTE: The last parameter defines the rotation angle in degree. + getRotationPtr()->setValue(static_cast(o)->value(), Base::toRadians(angle)); + return 0; + } + + PyErr_Clear(); + if (PyArg_ParseTuple(args, "O!d", &(Base::MatrixPy::Type), &o, &angle)) { + // NOTE: The last parameter defines the rotation angle in degree. + getRotationPtr()->setValue(static_cast(o)->value()); + return 0; } PyErr_Clear(); @@ -96,6 +103,43 @@ int RotationPy::PyInit(PyObject* args, PyObject* /*kwd*/) return 0; } + double a11 = 1.0, a12 = 0.0, a13 = 0.0, a14 = 0.0; + double a21 = 0.0, a22 = 1.0, a23 = 0.0, a24 = 0.0; + double a31 = 0.0, a32 = 0.0, a33 = 1.0, a34 = 0.0; + double a41 = 0.0, a42 = 0.0, a43 = 0.0, a44 = 1.0; + + // try read a 4x4 matrix + PyErr_Clear(); + if (PyArg_ParseTuple(args, "dddddddddddddddd", + &a11, &a12, &a13, &a14, + &a21, &a22, &a23, &a24, + &a31, &a32, &a33, &a34, + &a41, &a42, &a43, &a44)) + { + Matrix4D mtx(a11, a12, a13, a14, + a21, a22, a23, a24, + a31, a32, a33, a34, + a41, a42, a43, a44); + getRotationPtr()->setValue(mtx); + return 0; + } + + // try read a 3x3 matrix + PyErr_Clear(); + if (PyArg_ParseTuple(args, "ddddddddd", + &a11, &a12, &a13, + &a21, &a22, &a23, + &a31, &a32, &a33)) + { + Matrix4D mtx(a11, a12, a13, a14, + a21, a22, a23, a24, + a31, a32, a33, a34, + a41, a42, a43, a44); + getRotationPtr()->setValue(mtx); + return 0; + } + + PyErr_Clear(); PyObject *v1, *v2; if (PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type), &v1, @@ -112,7 +156,11 @@ int RotationPy::PyInit(PyObject* args, PyObject* /*kwd*/) "-- four floats (a quaternion)\n" "-- three floats (yaw, pitch, roll)" "-- Vector (rotation axis) and float (rotation angle)\n" - "-- two Vectors (two axes)"); + "-- two Vectors (two axes)\n" + "-- Matrix object\n" + "-- 16 floats (4x4 matrix)\n" + "-- 9 floats (3x3 matrix)\n" + ); return -1; } diff --git a/src/Base/Uuid.cpp b/src/Base/Uuid.cpp index c75b5fa2a..633b3b191 100644 --- a/src/Base/Uuid.cpp +++ b/src/Base/Uuid.cpp @@ -27,6 +27,8 @@ # include #endif +#include + /// Here the FreeCAD includes sorted by Base,App,Gui...... #include "Uuid.h" #include "Exception.h" diff --git a/src/Gui/ActiveObjectList.cpp b/src/Gui/ActiveObjectList.cpp new file mode 100644 index 000000000..b11ce692c --- /dev/null +++ b/src/Gui/ActiveObjectList.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** +* (c) Jürgen Riegel (juergen.riegel@web.de) 2014 * +* * +* This file is part of the FreeCAD CAx development system. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Library General Public License (LGPL) * +* as published by the Free Software Foundation; either version 2 of * +* the License, or (at your option) any later version. * +* for detail see the LICENCE text file. * +* * +* FreeCAD is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public * +* License along with FreeCAD; if not, write to the Free Software * +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +* USA * +* * +* Juergen Riegel 2014 * +***************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ + +#endif + +#include "ActiveObjectList.h" +#include +#include +#include + + + +using namespace Gui; + + +void Gui::ActiveObjectList::setObject(App::DocumentObject* obj, const char* name, const Gui::HighlightMode& mode) +{ + if (obj){ + if (hasObject(name)){ + Gui::Application::Instance->activeDocument()->signalHighlightObject(*dynamic_cast(Gui::Application::Instance->activeDocument()->getViewProvider(getObject(name))), mode, false); + } + _ObjectMap[name] = obj; + + Gui::Application::Instance->activeDocument()->signalHighlightObject(*dynamic_cast(Gui::Application::Instance->activeDocument()->getViewProvider(obj)), mode, true); + } +} + +bool Gui::ActiveObjectList::hasObject(const char*name)const +{ + return _ObjectMap.find(name) != _ObjectMap.end(); +} + +void ActiveObjectList::objectDeleted(const ViewProviderDocumentObject& viewProviderIn) +{ + App::DocumentObject* object = viewProviderIn.getObject(); + //maybe boost::bimap or boost::multi_index + std::map::iterator it; + for (it = _ObjectMap.begin(); it != _ObjectMap.end(); ++it) + { + if (it->second == object) + { + _ObjectMap.erase(it); + return; + } + } +} diff --git a/src/Gui/ActiveObjectList.h b/src/Gui/ActiveObjectList.h new file mode 100644 index 000000000..43669e5b0 --- /dev/null +++ b/src/Gui/ActiveObjectList.h @@ -0,0 +1,74 @@ +/*************************************************************************** +* (c) Jürgen Riegel (juergen.riegel@web.de) 2014 * +* * +* This file is part of the FreeCAD CAx development system. * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Library General Public License (LGPL) * +* as published by the Free Software Foundation; either version 2 of * +* the License, or (at your option) any later version. * +* for detail see the LICENCE text file. * +* * +* FreeCAD is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU Library General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public * +* License along with FreeCAD; if not, write to the Free Software * +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * +* USA * +* * +* Juergen Riegel 2014 * +***************************************************************************/ + + +#ifndef GUI_ActiveObjectList_H +#define GUI_ActiveObjectList_H + +#include +#include "Tree.h" +namespace App { + class DocumentObject; +} + +namespace Gui +{ + + class Document; + class ViewProviderDocumentObject; + + /** List of active or special objects + * This class holds a list of objects with a special name. + * Its mainly used to points to something like the active Body or Part in a edit session. + * The class is used the viewer (editor) of a document. + * @see Gui::MDIViewer + * @author Jürgen Riegel + */ + class GuiExport ActiveObjectList + { + + public: + template + inline _T getObject(const char* name) const + { + std::map::const_iterator pos = _ObjectMap.find(name); + return pos == _ObjectMap.end() ? 0 : dynamic_cast<_T>(pos->second); + } + void setObject(App::DocumentObject*, const char*, const Gui::HighlightMode& m = Gui::LightBlue); + bool hasObject(const char*)const; + void objectDeleted(const ViewProviderDocumentObject& viewProviderIn); + protected: + std::map _ObjectMap; + + + }; + + + +} //namespace Gui + +static const char PDBODYKEY[] = "pdbody"; +static const char PARTKEY[] = "part"; + +#endif diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 1be3a9d48..7e60e9e98 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) 2004 Jürgen Riegel * + * Copyright (c) 2004 Juergen Riegel * * * * This file is part of the FreeCAD CAx development system. * * * @@ -103,7 +103,13 @@ #include "ViewProviderAnnotation.h" #include "ViewProviderMeasureDistance.h" #include "ViewProviderPlacement.h" +#include "ViewProviderOriginFeature.h" #include "ViewProviderPlane.h" +#include "ViewProviderLine.h" +#include "ViewProviderGeoFeatureGroup.h" +#include "ViewProviderOriginGroup.h" +#include "ViewProviderPart.h" +#include "ViewProviderOrigin.h" #include "ViewProviderMaterialObject.h" #include "Language/Translator.h" @@ -319,6 +325,15 @@ struct PyMethodDef FreeCADGui_methods[] = { {NULL, NULL} /* sentinel */ }; + +Gui::MDIView* Application::activeView(void) const +{ + if (activeDocument()) + return activeDocument()->getActiveView(); + else + return NULL; +} + } // namespace Gui Application::Application(bool GUIenabled) @@ -1529,7 +1544,14 @@ void Application::initTypes(void) Gui::ViewProviderPythonFeature ::init(); Gui::ViewProviderPythonGeometry ::init(); Gui::ViewProviderPlacement ::init(); + Gui::ViewProviderOriginFeature ::init(); Gui::ViewProviderPlane ::init(); + Gui::ViewProviderLine ::init(); + Gui::ViewProviderGeoFeatureGroup ::init(); + Gui::ViewProviderGeoFeatureGroupPython ::init(); + Gui::ViewProviderOriginGroup ::init(); + Gui::ViewProviderPart ::init(); + Gui::ViewProviderOrigin ::init(); Gui::ViewProviderMaterialObject ::init(); Gui::ViewProviderMaterialObjectPython ::init(); diff --git a/src/Gui/Application.h b/src/Gui/Application.h index 96baeb1dc..d5d8e71ee 100644 --- a/src/Gui/Application.h +++ b/src/Gui/Application.h @@ -147,7 +147,9 @@ public: * If no such document exists 0 is returned. */ Gui::Document* getDocument(const App::Document* pDoc) const; - /// Shows the associated view provider of the given object + /// Getter for the active view of the active document or null + Gui::MDIView* activeView(void) const; + /// Shows the associated view provider of the given object void showViewProvider(const App::DocumentObject*); /// Hides the associated view provider of the given object void hideViewProvider(const App::DocumentObject*); @@ -232,6 +234,7 @@ public: PYFUNCDEF_S(sActiveDocument); PYFUNCDEF_S(sSetActiveDocument); + PYFUNCDEF_S(sActiveView); PYFUNCDEF_S(sGetDocument); PYFUNCDEF_S(sDoCommand); diff --git a/src/Gui/ApplicationPy.cpp b/src/Gui/ApplicationPy.cpp index 7a6992d2e..1e3833fd5 100644 --- a/src/Gui/ApplicationPy.cpp +++ b/src/Gui/ApplicationPy.cpp @@ -139,13 +139,16 @@ PyMethodDef Application::Methods[] = { "Open a macro, Inventor or VRML file"}, {"export", (PyCFunction) Application::sExport, 1, "save scene to Inventor or VRML file"}, - {"activeDocument", (PyCFunction) Application::sActiveDocument, 1, + { "activeDocument", (PyCFunction)Application::sActiveDocument, 1, "activeDocument() -> object or None\n\n" - "Return the active document or None if no one exists"}, + "Return the active document or None if no one exists" }, {"setActiveDocument", (PyCFunction) Application::sSetActiveDocument,1, "setActiveDocument(string or App.Document) -> None\n\n" "Activate the specified document"}, - {"getDocument", (PyCFunction) Application::sGetDocument, 1, + { "activeView", (PyCFunction)Application::sActiveView, 1, + "activeView() -> object or None\n\n" + "Return the active view of the active document or None if no one exists" }, + { "getDocument", (PyCFunction)Application::sGetDocument, 1, "getDocument(string) -> object\n\n" "Get a document by its name"}, {"doCommand", (PyCFunction) Application::sDoCommand, 1, @@ -167,17 +170,34 @@ PyMethodDef Application::Methods[] = { {NULL, NULL} /* Sentinel */ }; -PyObject* Gui::Application::sActiveDocument(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/) +PyObject* Gui::Application::sActiveDocument(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) { - if (!PyArg_ParseTuple(args, "")) // convert args: Python->C - return NULL; // NULL triggers exception + if (!PyArg_ParseTuple(args, "")) // convert args: Python->C + return NULL; // NULL triggers exception - Document *pcDoc = Instance->activeDocument(); - if (pcDoc) { - return pcDoc->getPyObject(); - } else { - Py_Return; - } + Document *pcDoc = Instance->activeDocument(); + if (pcDoc) { + return pcDoc->getPyObject(); + } + else { + Py_Return; + } +} + +PyObject* Gui::Application::sActiveView(PyObject * /*self*/, PyObject *args, PyObject * /*kwd*/) +{ + if (!PyArg_ParseTuple(args, "")) // convert args: Python->C + return NULL; // NULL triggers exception + + Document *pcDoc = Instance->activeDocument(); + if (pcDoc) { + Gui::MDIView *pcView = pcDoc->getActiveView(); + if (pcView) + // already incremented in getPyObject(). + return pcView->getPyObject(); + } + + Py_Return; } PyObject* Gui::Application::sSetActiveDocument(PyObject * /*self*/, PyObject *args,PyObject * /*kwd*/) diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 26d9d46a4..34bc3b75b 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -33,6 +33,7 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/propertyeditor ${CMAKE_CURRENT_BINARY_DIR}/TaskView ${CMAKE_CURRENT_BINARY_DIR}/Quarter + ${CMAKE_CURRENT_BINARY_DIR}/DAGView ${Boost_INCLUDE_DIRS} ${COIN3D_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS} @@ -199,6 +200,7 @@ set(Gui_MOC_HDRS DlgSettingsMacroImp.h DlgSettingsUnitsImp.h DlgTipOfTheDayImp.h + DlgCheckableMessageBox.h DlgToolbarsImp.h DlgWorkbenchesImp.h TaskDlgRelocation.h @@ -260,6 +262,9 @@ set(Gui_MOC_HDRS TaskView/TaskWatcher.h TaskView/TaskEditControl.h TaskView/TaskView.h + DAGView/DAGView.h + DAGView/DAGModel.h + DAGView/DAGRectItem.h ) #qt4_wrap_cpp(Gui_MOC_SRCS ${Gui_MOC_HDRS}) fc_wrap_cpp(Gui_MOC_SRCS ${Gui_MOC_HDRS}) @@ -305,6 +310,7 @@ SET(Gui_UIC_SRCS DlgSettingsDocument.ui DlgSettingsImage.ui DlgSettingsMacro.ui + DlgCheckableMessageBox.ui DlgTipOfTheDay.ui DlgToolbars.ui DlgWorkbenches.ui @@ -376,6 +382,7 @@ SET(Dialog_CPP_SRCS DlgTipOfTheDayImp.cpp DlgExpressionInput.cpp TaskDlgRelocation.cpp + DlgCheckableMessageBox.cpp DlgUndoRedo.cpp InputVector.cpp Placement.cpp @@ -405,6 +412,7 @@ SET(Dialog_HPP_SRCS DlgProjectInformationImp.h DlgProjectUtility.h DlgPropertyLink.h + DlgCheckableMessageBox.h DlgTipOfTheDayImp.h DlgExpressionInput.h TaskDlgRelocation.h @@ -443,6 +451,7 @@ SET(Dialog_SRCS DlgProjectUtility.ui DlgPropertyLink.ui DlgTipOfTheDay.ui + DlgCheckableMessageBox.ui DlgTreeWidget.ui DlgExpressionInput.ui DownloadManager.ui @@ -551,6 +560,11 @@ SET(Dock_Windows_CPP_SRCS Tree.cpp TreeView.cpp ProjectView.cpp + DAGView/DAGView.cpp + DAGView/DAGModel.cpp + DAGView/DAGRectItem.cpp + DAGView/DAGModelGraph.cpp + DAGView/DAGFilter.cpp ) SET(Dock_Windows_HPP_SRCS CombiView.h @@ -563,6 +577,11 @@ SET(Dock_Windows_HPP_SRCS Tree.h TreeView.h ProjectView.h + DAGView/DAGView.h + DAGView/DAGModel.h + DAGView/DAGRectItem.h + DAGView/DAGModelGraph.h + DAGView/DAGFilter.h ) SET(Dock_Windows_SRCS ${Dock_Windows_CPP_SRCS} @@ -815,7 +834,13 @@ SET(Viewprovider_CPP_SRCS ViewProviderVRMLObject.cpp ViewProviderBuilder.cpp ViewProviderPlacement.cpp + ViewProviderOriginFeature.cpp ViewProviderPlane.cpp + ViewProviderLine.cpp + ViewProviderGeoFeatureGroup.cpp + ViewProviderOriginGroup.cpp + ViewProviderPart.cpp + ViewProviderOrigin.cpp ViewProviderMaterialObject.cpp ) SET(Viewprovider_SRCS @@ -833,7 +858,13 @@ SET(Viewprovider_SRCS ViewProviderVRMLObject.h ViewProviderBuilder.h ViewProviderPlacement.h + ViewProviderOriginFeature.h ViewProviderPlane.h + ViewProviderLine.h + ViewProviderGeoFeatureGroup.h + ViewProviderOriginGroup.h + ViewProviderPart.h + ViewProviderOrigin.h ViewProviderMaterialObject.h ) SOURCE_GROUP("View3D\\Viewprovider" FILES ${Viewprovider_SRCS}) @@ -924,10 +955,12 @@ SOURCE_GROUP("Widget" FILES ${Widget_SRCS}) SET(View_CPP_SRCS MDIView.cpp GraphvizView.cpp + ActiveObjectList.cpp ) SET(View_HPP_SRCS MDIView.h GraphvizView.h + ActiveObjectList.h ) SET(View_SRCS ${View_CPP_SRCS} diff --git a/src/Gui/Command.h b/src/Gui/Command.h index 36e9f3a17..4a5b88896 100644 --- a/src/Gui/Command.h +++ b/src/Gui/Command.h @@ -166,7 +166,6 @@ protected: /// Applies the menu text, tool and status tip to the passed action object void applyCommandData(const char* context, Action* ); const char* keySequenceToAccel(int) const; - void adjustCameraPosition(); //@} public: @@ -252,8 +251,6 @@ public: static void copyVisual(const char* to, const char* attr_to, const char* from, const char* attr_from); /// Get Python tuple from object and sub-elements static std::string getPythonTuple(const std::string& name, const std::vector& subnames); - /// import an external module only once - //static void addModule(const char* sModuleName); /// translate a string to a python string literal (needed e.g. in file names for windows...) const std::string strToPython(const char* Str); const std::string strToPython(const std::string &Str){return strToPython(Str.c_str());}; @@ -288,6 +285,12 @@ public: const char* getGroupName() const { return sGroup; } void setGroupName(const char*); //@} + + + /** @name arbitrary helper methods */ + //@{ + void adjustCameraPosition(); + //@} protected: enum CmdType { diff --git a/src/Gui/CommandDoc.cpp b/src/Gui/CommandDoc.cpp index 423b389b1..5c6a91185 100644 --- a/src/Gui/CommandDoc.cpp +++ b/src/Gui/CommandDoc.cpp @@ -28,6 +28,7 @@ # include # include # include +# include # include # include # include @@ -44,6 +45,7 @@ #include #include #include +#include #include "Action.h" #include "Application.h" @@ -558,7 +560,7 @@ DEF_STD_CMD_A(StdCmdProjectInfo); StdCmdProjectInfo::StdCmdProjectInfo() :Command("Std_ProjectInfo") { - // seting the + // seting the sGroup = QT_TR_NOOP("File"); sMenuText = QT_TR_NOOP("Project i&nformation..."); sToolTipText = QT_TR_NOOP("Show details of the currently active project"); @@ -589,7 +591,7 @@ DEF_STD_CMD_A(StdCmdProjectUtil); StdCmdProjectUtil::StdCmdProjectUtil() :Command("Std_ProjectUtil") { - // seting the + // seting the sGroup = QT_TR_NOOP("Tools"); sWhatsThis = "Std_ProjectUtil"; sMenuText = QT_TR_NOOP("Project utility..."); @@ -1067,15 +1069,22 @@ void StdCmdDelete::activated(int iMsg) } else { // check if we can delete the object + std::set affectedLabels; for (std::vector::iterator ft = sel.begin(); ft != sel.end(); ++ft) { App::DocumentObject* obj = ft->getObject(); std::vector links = obj->getInList(); if (!links.empty()) { // check if the referenced objects are groups or are selected too for (std::vector::iterator lt = links.begin(); lt != links.end(); ++lt) { - if (!(*lt)->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId()) && !rSel.isSelected(*lt)) { + if ( + (!(*lt)->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId())) && + (!(*lt)->getTypeId().isDerivedFrom(App::Origin::getClassTypeId())) && + (!rSel.isSelected(*lt)) && + (!(*lt)->getTypeId().isDerivedFrom(Base::Type::fromName("Part::BodyBase"))) + ){ + // TODO Do something with this hack of Part::BodyBase (2015-09-09, Fat-Zer) autoDeletion = false; - break; + affectedLabels.insert(QString::fromUtf8((*lt)->Label.getValue())); } } @@ -1086,10 +1095,16 @@ void StdCmdDelete::activated(int iMsg) } if (!autoDeletion) { + QString bodyMessage; + QTextStream bodyMessageStream(&bodyMessage); + bodyMessageStream << qApp->translate("Std_Delete", + "The following, referencing objects might break.\n\n" + "Are you sure you want to continue?\n\n"); + for (const auto ¤tLabel : affectedLabels) + bodyMessageStream << currentLabel << '\n'; + int ret = QMessageBox::question(Gui::getMainWindow(), - qApp->translate("Std_Delete", "Object dependencies"), - qApp->translate("Std_Delete", "This object is referenced by other objects and thus these objects might get broken.\n" - "Are you sure to continue?"), + qApp->translate("Std_Delete", "Object dependencies"), bodyMessage, QMessageBox::Yes, QMessageBox::No); if (ret == QMessageBox::Yes) autoDeletion = true; @@ -1112,6 +1127,7 @@ void StdCmdDelete::activated(int iMsg) } } } + doCommand(Doc,"App.getDocument(\"%s\").recompute()", (*it)->getName()); } } @@ -1145,7 +1161,7 @@ void StdCmdRefresh::activated(int iMsg) //testing the changes of properties. //openCommand("Refresh active document"); doCommand(Doc,"App.activeDocument().recompute()"); - //commitCommand(); + //commitCommand(); } } diff --git a/src/Gui/Control.cpp b/src/Gui/Control.cpp index d0b6c99c3..c5322e7be 100644 --- a/src/Gui/Control.cpp +++ b/src/Gui/Control.cpp @@ -124,7 +124,7 @@ void ControlSingleton::showDialog(Gui::TaskView::TaskDialog *dlg) if (ActiveDialog == dlg) return; // dialog is already defined ActiveDialog = dlg; - connect(dlg, SIGNAL(destroyed()), this, SLOT(closedDialog())); + connect(dlg, SIGNAL(aboutToBeDestroyed()), this, SLOT(closedDialog())); } // not all workbenches have the combo view enabled else if (!_taskPanel) { diff --git a/src/Gui/DAGView/DAGFilter.cpp b/src/Gui/DAGView/DAGFilter.cpp new file mode 100644 index 000000000..dc9857f50 --- /dev/null +++ b/src/Gui/DAGView/DAGFilter.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#endif + +#include +#include + + +#include "DAGFilter.h" + +using namespace Gui; +using namespace DAG; + +FilterBase::FilterBase() : name(QString::fromAscii("empty name")), enabled(true), type(Type::Exclusion) +{ + +} + +FilterOrigin::FilterOrigin() : FilterBase() +{ + name = QObject::tr("Origin"); +} + +bool FilterOrigin::goFilter(const Vertex &vertexIn, const Graph &graphIn, const GraphLinkContainer &linkIn) const +{ + Base::Type originType = Base::Type::fromName("App::Origin"); + assert (originType != Base::Type::badType()); + //if child of origin hide. + InEdgeIterator it, itEnd; + for (boost::tie(it, itEnd) = boost::in_edges(vertexIn, graphIn); it != itEnd; ++it) + { + Vertex source = boost::source(*it, graphIn); + const GraphLinkRecord &sourceRecord = findRecord(source, linkIn); + if + ( + (sourceRecord.DObject->getTypeId() == originType) && + (boost::in_degree(vertexIn, graphIn) == 1) + ) + return true; + } + return false; +} + +FilterTyped::FilterTyped(const std::string &typeIn) : FilterBase(), type(typeIn) +{ + name = QString::fromStdString(typeIn); +} + +bool FilterTyped::goFilter(const Gui::DAG::Vertex& vertexIn, const Graph& graphIn, const GraphLinkContainer& linkIn) const +{ + if (type.empty()) + return false; + Base::Type theType = Base::Type::fromName(type.c_str()); + if (theType == Base::Type::badType()) + return false; + + const GraphLinkRecord &sourceRecord = findRecord(vertexIn, linkIn); + if (sourceRecord.DObject->getTypeId() == theType) + return true; + + return false; +} + + diff --git a/src/Gui/DAGView/DAGFilter.h b/src/Gui/DAGView/DAGFilter.h new file mode 100644 index 000000000..0ceb90aae --- /dev/null +++ b/src/Gui/DAGView/DAGFilter.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef DAGFILTER_H +#define DAGFILTER_H + +#include + +#include "DAGModelGraph.h" + +namespace Gui +{ + class ViewProviderDocumentObject; + namespace DAG + { + class FilterBase + { + public: + enum class Type + { + None = 0, //!< no type designation. shouldn't be used. + Inclusion, + Exclusion + }; + FilterBase(); + //! @return is whether we have a match or not. + virtual bool goFilter(const Vertex &vertexIn, const Graph &graphIn, const GraphLinkContainer &linkIn) const = 0; + QString name; + bool enabled; + Type type; + }; + + /*! Hide all children of app::origin that are not + * used by subsequent features + */ + class FilterOrigin : public FilterBase + { + public: + FilterOrigin(); + virtual bool goFilter(const Vertex &vertexIn, const Graph &graphIn, const GraphLinkContainer &linkIn) const override; + }; + + /*! Hide nodes of type*/ + class FilterTyped : public FilterBase + { + public: + explicit FilterTyped(const std::string &typeIn); + std::string type; + virtual bool goFilter(const Vertex &vertexIn, const Graph &graphIn, const GraphLinkContainer &linkIn) const override; + }; + } +} + +#endif // DAGFILTER_H diff --git a/src/Gui/DAGView/DAGModel.cpp b/src/Gui/DAGView/DAGModel.cpp new file mode 100644 index 000000000..bdd0ed764 --- /dev/null +++ b/src/Gui/DAGView/DAGModel.cpp @@ -0,0 +1,1202 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DAGModel.h" + +using namespace Gui; +using namespace DAG; + +LineEdit::LineEdit(QWidget* parentIn): QLineEdit(parentIn) +{ + +} + +void LineEdit::keyPressEvent(QKeyEvent *eventIn) +{ + if (eventIn->key() == Qt::Key_Escape) + { + Q_EMIT rejectedSignal(); + eventIn->accept(); + return; + } + if ( + (eventIn->key() == Qt::Key_Enter) || + (eventIn->key() == Qt::Key_Return) + ) + { + Q_EMIT acceptedSignal(); + eventIn->accept(); + return; + } + + QLineEdit::keyPressEvent(eventIn); +} + +//I dont think I should have to call invalidate +//and definitely not on the whole scene! +//if we have performance problems, this will definitely +//be something to re-visit. I am not wasting anymore time on +//this right now. +// this->scene()->invalidate(); +// this->scene()->invalidate(this->sceneTransform().inverted().mapRect(this->boundingRect())); +// update(boundingRect()); +//note: I haven't tried this again since I turned BSP off. + +Model::Model(QObject *parentIn, const Gui::Document &documentIn) : QGraphicsScene(parentIn) +{ + //turned off BSP as it was giving inconsistent discovery of items + //underneath cursor. + this->setItemIndexMethod(QGraphicsScene::NoIndex); + + theGraph = std::shared_ptr(new Graph()); + graphLink = std::shared_ptr(new GraphLinkContainer()); + setupViewConstants(); + setupFilters(); + + graphDirty = false; + currentPrehighlight = nullptr; + + ParameterGrp::handle group = App::GetApplication().GetUserParameter(). + GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DAGView"); + selectionMode = static_cast(group->GetInt("SelectionMode", 0)); + group->SetInt("SelectionMode", static_cast(selectionMode)); //ensure entry exists. + + QIcon temp(Gui::BitmapFactory().pixmap("dagViewVisible")); + visiblePixmapEnabled = temp.pixmap(iconSize, iconSize, QIcon::Normal, QIcon::On); + visiblePixmapDisabled = temp.pixmap(iconSize, iconSize, QIcon::Disabled, QIcon::Off); + + QIcon passIcon(Gui::BitmapFactory().pixmap("dagViewPass")); + passPixmap = passIcon.pixmap(iconSize, iconSize); + QIcon failIcon(Gui::BitmapFactory().pixmap("dagViewFail")); + failPixmap = failIcon.pixmap(iconSize, iconSize); + QIcon pendingIcon(Gui::BitmapFactory().pixmap("dagViewPending")); + pendingPixmap = pendingIcon.pixmap(iconSize, iconSize); + + renameAction = new QAction(this); + renameAction->setText(tr("Rename")); + renameAction->setStatusTip(tr("Rename object")); + renameAction->setShortcut(Qt::Key_F2); + connect(renameAction, SIGNAL(triggered()), this, SLOT(onRenameSlot())); + + editingFinishedAction = new QAction(this); + editingFinishedAction->setText(tr("Finish editing")); + editingFinishedAction->setStatusTip(tr("Finish editing object")); + connect(this->editingFinishedAction, SIGNAL(triggered()), + this, SLOT(editingFinishedSlot())); + + connectNewObject = documentIn.signalNewObject.connect(boost::bind(&Model::slotNewObject, this, _1)); + connectDelObject = documentIn.signalDeletedObject.connect(boost::bind(&Model::slotDeleteObject, this, _1)); + connectChgObject = documentIn.signalChangedObject.connect(boost::bind(&Model::slotChangeObject, this, _1, _2)); + connectEdtObject = documentIn.signalInEdit.connect(boost::bind(&Model::slotInEdit, this, _1)); + connectResObject = documentIn.signalResetEdit.connect(boost::bind(&Model::slotResetEdit, this, _1)); +} + +Model::~Model() +{ + if (connectNewObject.connected()) + connectNewObject.disconnect(); + if (connectDelObject.connected()) + connectDelObject.disconnect(); + if (connectChgObject.connected()) + connectChgObject.disconnect(); + if(connectEdtObject.connected()) + connectEdtObject.disconnect(); + if(connectResObject.connected()) + connectResObject.disconnect(); + + removeAllItems(); +} + +void Model::setupFilters() +{ +// filters.push_back(std::shared_ptr(new FilterOrigin())); +// filters.push_back(std::shared_ptr(new FilterTyped("PartDesign::Body"))); +// filters.push_back(std::shared_ptr(new FilterTyped("App::Part"))); +} + +void Model::setupViewConstants() +{ + ParameterGrp::handle group = App::GetApplication().GetUserParameter(). + GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DAGView"); + + //get font point size. + int fontPointSize = group->GetInt("FontPointSize", 0); + group->SetInt("FontPointSize", fontPointSize); //ensure entry exists. + if (fontPointSize != 0) + { + QFont tempFont(this->font()); + tempFont.setPointSize(fontPointSize); + this->setFont(tempFont); + } + + //get direction + direction = group->GetFloat("Direction", 1.0); + if (direction != -1.0 && direction != 1.0) + direction = 1.0; + group->SetFloat("Direction", direction); //ensure entry exists. + + QFontMetrics fontMetric(this->font()); + fontHeight = fontMetric.height(); + verticalSpacing = 1.0; + rowHeight = (fontHeight + 2.0 * verticalSpacing) * direction; //pixel space top and bottom. + iconSize = fontHeight; + pointSize = fontHeight / 2.0; + pointSpacing = pointSize; + pointToIcon = iconSize; + iconToIcon = iconSize * 0.25; + iconToText = iconSize / 2.0; + rowPadding = fontHeight; + backgroundBrushes = {this->palette().base(), this->palette().alternateBase()}; + forgroundBrushes = + { + QBrush(Qt::red), + QBrush(Qt::darkRed), + QBrush(Qt::green), + QBrush(Qt::darkGreen), + QBrush(Qt::blue), + QBrush(Qt::darkBlue), + QBrush(Qt::cyan), + QBrush(Qt::darkCyan), + QBrush(Qt::magenta), + QBrush(Qt::darkMagenta), +// QBrush(Qt::yellow), can't read + QBrush(Qt::darkYellow), + QBrush(Qt::gray), + QBrush(Qt::darkGray), + QBrush(Qt::lightGray) + }; //reserve some of the these for highlight stuff. +} + +void Model::slotNewObject(const ViewProviderDocumentObject &VPDObjectIn) +{ + Vertex virginVertex = boost::add_vertex(*theGraph); + + addVertexItemsToScene(virginVertex); + + GraphLinkRecord virginRecord; + virginRecord.DObject = VPDObjectIn.getObject(); + virginRecord.VPDObject = &VPDObjectIn; + virginRecord.rectItem = (*theGraph)[virginVertex].rectangle.get(); + virginRecord.uniqueName = std::string(virginRecord.DObject->getNameInDocument()); + virginRecord.vertex = virginVertex; + graphLink->insert(virginRecord); + + //setup rectangle. + auto *rectangle = (*theGraph)[virginVertex].rectangle.get(); + rectangle->setEditingBrush(QBrush(Qt::yellow)); + + (*theGraph)[virginVertex].icon->setPixmap(VPDObjectIn.getIcon().pixmap(iconSize, iconSize)); + (*theGraph)[virginVertex].stateIcon->setPixmap(passPixmap); + (*theGraph)[virginVertex].text->setFont(this->font()); + + graphDirty = true; +} + +void Model::slotDeleteObject(const ViewProviderDocumentObject &VPDObjectIn) +{ + Vertex vertex = findRecord(&VPDObjectIn, *graphLink).vertex; + + //remove items from scene. + removeVertexItemsFromScene(vertex); + + //remove connector items + auto outRange = boost::out_edges(vertex, *theGraph); + for (auto outEdgeIt = outRange.first; outEdgeIt != outRange.second; ++outEdgeIt) + this->removeItem((*theGraph)[*outEdgeIt].connector.get()); + auto inRange = boost::in_edges(vertex, *theGraph); + for (auto inEdgeIt = inRange.first; inEdgeIt != inRange.second; ++inEdgeIt) + this->removeItem((*theGraph)[*inEdgeIt].connector.get()); + + //remove the actual vertex. + boost::clear_vertex(vertex, *theGraph); + boost::remove_vertex(vertex, *theGraph); + + eraseRecord(&VPDObjectIn, *graphLink); + graphDirty = true; +} + +void Model::slotChangeObject(const ViewProviderDocumentObject &VPDObjectIn, const App::Property& propertyIn) +{ + std::string name("Empty Name"); + if (propertyIn.getName()) //getName can return 0. + name = propertyIn.getName(); + assert(!name.empty()); + +// std::cout << std::endl << "inside changed object." << std::endl << +// "Property name is: " << name << std::endl << +// "Property type is: " << propertyIn.getTypeId().getName() << std::endl << std::endl; + + //renaming of objects. + if (std::string("Label") == name) + { + const GraphLinkRecord &record = findRecord(&VPDObjectIn, *graphLink); + auto *text = (*theGraph)[record.vertex].text.get(); + text->setPlainText(QString::fromUtf8(record.DObject->Label.getValue())); + } + + //link changes. these require a recalculation of connectors. + const static std::unordered_set linkTypes = + { + "App::PropertyLink", + "App::PropertyLinkList", + "App::PropertyLinkSub", + "App::PropertyLinkSubList" + }; + + if (linkTypes.find(propertyIn.getTypeId().getName()) != linkTypes.end()) + { + const GraphLinkRecord &record = findRecord(&VPDObjectIn, *graphLink); + boost::clear_vertex(record.vertex, *theGraph); + graphDirty = true; + } +} + +void Model::slotInEdit(const ViewProviderDocumentObject& VPDObjectIn) +{ + RectItem *rect = (*theGraph)[findRecord(&VPDObjectIn, *graphLink).vertex].rectangle.get(); + rect->editingStart(); + this->invalidate(); +} + +void Model::slotResetEdit(const ViewProviderDocumentObject& VPDObjectIn) +{ + RectItem *rect = (*theGraph)[findRecord(&VPDObjectIn, *graphLink).vertex].rectangle.get(); + rect->editingFinished(); + this->invalidate(); +} + +void Model::selectionChanged(const SelectionChanges& msg) +{ + //note that treeview uses set selection which sends a message with just a document name + //and no object name. Have to explore further. + + auto getAllEdges = [this](const Vertex &vertexIn) + { + //is there really no function to get both in and out edges? + std::vector out; + + OutEdgeIterator outIt, outItEnd; + for (boost::tie(outIt, outItEnd) = boost::out_edges(vertexIn, *theGraph); outIt != outItEnd; ++outIt) + out.push_back(*outIt); + + InEdgeIterator inIt, inItEnd; + for (boost::tie(inIt, inItEnd) = boost::in_edges(vertexIn, *theGraph); inIt != inItEnd; ++inIt) + out.push_back(*inIt); + + return out; + }; + + auto highlightConnectorOn = [this, getAllEdges](const Vertex &vertexIn) + { + QColor color = (*theGraph)[vertexIn].text->defaultTextColor(); + QPen pen(color); + pen.setWidth(3.0); + auto edges = getAllEdges(vertexIn); + for (auto edge : edges) + { + (*theGraph)[edge].connector->setPen(pen); + (*theGraph)[edge].connector->setZValue(1.0); + } + }; + + auto highlightConnectorOff = [this, getAllEdges](const Vertex &vertexIn) + { + auto edges = getAllEdges(vertexIn); + for (auto edge : edges) + { + (*theGraph)[edge].connector->setPen(QPen()); + (*theGraph)[edge].connector->setZValue(0.0); + } + }; + + //lamda for clearing selections. + auto clearSelection = [this, highlightConnectorOff]() + { + BGL_FORALL_VERTICES(currentVertex, *theGraph, Graph) + { + RectItem *rect = (*theGraph)[currentVertex].rectangle.get(); + assert(rect); + rect->selectionOff(); + highlightConnectorOff(currentVertex); + } + }; + + //lamda for getting rectangle. + auto getRectangle = [this](const char *in) + { + assert(in); + std::string name(in); + assert(!name.empty()); + const GraphLinkRecord &record = findRecord(name, *graphLink); + RectItem *rect = (*theGraph)[record.vertex].rectangle.get(); + assert(rect); + return rect; + }; + + if (msg.Type == SelectionChanges::AddSelection) + { + if (msg.pObjectName) + { + RectItem *rect = getRectangle(msg.pObjectName); + rect->selectionOn(); + highlightConnectorOn(findRecord(std::string(msg.pObjectName), *graphLink).vertex); + } + } + else if(msg.Type == SelectionChanges::RmvSelection) + { + if (msg.pObjectName) + { + RectItem *rect = getRectangle(msg.pObjectName); + rect->selectionOff(); + highlightConnectorOff(findRecord(std::string(msg.pObjectName), *graphLink).vertex); + } + } + else if(msg.Type == SelectionChanges::SetSelection) + { + clearSelection(); + + auto selections = Gui::Selection().getSelection(msg.pDocName); + for (const auto &selection : selections) + { + assert(selection.FeatName); + RectItem *rect = getRectangle(selection.FeatName); + rect->selectionOn(); + highlightConnectorOn(findRecord(selection.FeatName, *graphLink).vertex); + } + } + else if(msg.Type == SelectionChanges::ClrSelection) + { + clearSelection(); + } + + this->invalidate(); +} + +void Model::awake() +{ + if (graphDirty) + { + updateSlot(); + this->invalidate(); + } + updateStates(); +} + +void Model::updateSlot() +{ + //empty outList means it is a root. + //empty inList means it is a leaf. + + //NOTE: some of the following loops can/should be combined + //for speed. Not doing yet, as I want a simple algorithm until + //a more complete picture is formed. + + Base::TimeInfo startTime; + + //here we will cycle through the graph updating edges. + //we have to do this first and in isolation because everything is dependent on an up to date graph. + BGL_FORALL_VERTICES(currentVertex, *theGraph, Graph) + { + const App::DocumentObject *currentDObject = findRecord(currentVertex, *graphLink).DObject; + std::vector otherDObjects = currentDObject->getOutList(); + for (auto ¤tOtherDObject : otherDObjects) + { + Vertex otherVertex = findRecord(currentOtherDObject, *graphLink).vertex; + bool result; + Edge edge; + boost::tie(edge, result) = boost::add_edge(currentVertex, otherVertex, *theGraph); + if (result) + { + (*theGraph)[edge].connector = std::shared_ptr(new QGraphicsPathItem()); + (*theGraph)[edge].connector->setZValue(0.0); + } + } + } + + //apply filters. + BGL_FORALL_VERTICES(currentVertex, *theGraph, Graph) + { + (*theGraph)[currentVertex].dagVisible = true; //default to shown. + for (const auto ¤tFilter : filters) + { + if (!currentFilter->enabled || currentFilter->type != FilterBase::Type::Exclusion) + continue; + if (currentFilter->goFilter(currentVertex, *theGraph, *graphLink)) + (*theGraph)[currentVertex].dagVisible = false; + } + } + //inclusion takes precedence. Separate loop because filters might probe + //children and parents. So we want to ensure all exclusions are done + //before inclusions start. + BGL_FORALL_VERTICES(currentVertex, *theGraph, Graph) + { + for (const auto ¤tFilter : filters) + { + if (!currentFilter->enabled || currentFilter->type != FilterBase::Type::Inclusion) + continue; + if (currentFilter->goFilter(currentVertex, *theGraph, *graphLink)) + (*theGraph)[currentVertex].dagVisible = true; + } + } + + //sync scene items to graph vertex dagVisible. + BGL_FORALL_VERTICES(currentVertex, *theGraph, Graph) + { + if ((*theGraph)[currentVertex].dagVisible && (!(*theGraph)[currentVertex].rectangle->scene())) + addVertexItemsToScene(currentVertex); + if ((!(*theGraph)[currentVertex].dagVisible) && (*theGraph)[currentVertex].rectangle->scene()) + removeVertexItemsFromScene(currentVertex); + } + + //sync scene items for graph edge. + BGL_FORALL_EDGES(currentEdge, *theGraph, Graph) + { + Vertex source = boost::source(currentEdge, *theGraph); + Vertex target = boost::target(currentEdge, *theGraph); + + bool edgeVisible = (*theGraph)[source].dagVisible && (*theGraph)[target].dagVisible; + if (edgeVisible && (!(*theGraph)[currentEdge].connector->scene())) + this->addItem((*theGraph)[currentEdge].connector.get()); + if ((!edgeVisible) && (*theGraph)[currentEdge].connector->scene()) + this->removeItem((*theGraph)[currentEdge].connector.get()); + } + + indexVerticesEdges(); + Path sorted; + try + { + boost::topological_sort(*theGraph, std::back_inserter(sorted)); + } + catch(const boost::not_a_dag &) + { + Base::Console().Error("not a dag exception in DAGView::Model::updateSlot()\n"); + return; + } + //index the vertices in sort order. + int tempIndex = 0; + for (const auto ¤tVertex : sorted) + { + (*theGraph)[currentVertex].topoSortIndex = tempIndex; + tempIndex++; + } + + //draw graph(nodes and connectors). + int currentRow = 0; + int currentColumn = -1; //we know first column is going to be root so will be kicked up to 0. + int maxColumn = currentColumn; //used for determining offset of icons and text. + float maxTextLength = 0; + for (const auto ¤tVertex : sorted) + { + if (!(*theGraph)[currentVertex].dagVisible) + continue; + + if (boost::out_degree(currentVertex, *theGraph) == 0) + currentColumn = 0; + else + { + //loop parents and find an acceptable column. + int farthestParentIndex = sorted.size(); + ColumnMask columnMask; + Path parentVertices; + OutEdgeIterator it, itEnd; + boost::tie(it, itEnd) = boost::out_edges(currentVertex, *theGraph); + for (;it != itEnd; ++it) + { +// std::cout << std::endl << "name: " << findRecord(currentVertex, *graphLink).DObject->Label.getValue() << std::endl; + + Vertex target = boost::target(*it, *theGraph); + parentVertices.push_back(target); + int currentParentIndex = (*theGraph)[target].topoSortIndex; + if (currentParentIndex < farthestParentIndex) + { + Path::const_iterator start = sorted.begin() + currentParentIndex + 1; // 1 after + Path::const_iterator end = sorted.begin() + (*theGraph)[currentVertex].topoSortIndex; // 1 before + Path::const_iterator it; + for (it = start; it != end; ++it) + { +// std::cout << " parent: " << findRecord(*it, *graphLink).DObject->Label.getValue() << std::endl; + + columnMask |= (*theGraph)[*it].column; + } + farthestParentIndex = currentParentIndex; + } + } + + //have to create a smaller subset to get through std::cout. +// std::bitset<8> testSet; +// for (unsigned int index = 0; index < testSet.size(); ++index) +// testSet[index]= columnMask[index]; +// std::cout << "mask for " << findRecord(currentVertex, *graphLink).DObject->Label.getValue() << " " << +// testSet.to_string() << std::endl; + + //now we should have a mask representing the columns that are being used. + //this is from the lowest parent, in the topo sort, to last entry. + + //try to use the same column as one of the parents.(*theGraph)[*it].column + int destinationColumn = 0; //default to first column + for (const auto ¤tParent : parentVertices) + { + if (((*theGraph)[currentParent].column & columnMask).none()) + { + //go with first visible parent for now. + if (!(*theGraph)[currentParent].dagVisible) + continue; + destinationColumn = static_cast(std::log2((*theGraph)[currentParent].column.to_ulong())); + break; + } + } + //if destination not valid look for the first open column. + if (columnMask.test(destinationColumn)) + { + for (std::size_t index = 0; index < columnMask.size(); ++index) + { + if (! columnMask.test(index)) + { + destinationColumn = index; + break; + } + } + } + + currentColumn = destinationColumn; + } + + assert(currentColumn < static_cast(ColumnMask().size())); //temp limitation. + + maxColumn = std::max(currentColumn, maxColumn); + QBrush currentBrush(forgroundBrushes.at(currentColumn % forgroundBrushes.size())); + + auto *rectangle = (*theGraph)[currentVertex].rectangle.get(); + rectangle->setRect(-rowPadding, 0.0, rowPadding, rowHeight); //calculate actual length later. + rectangle->setTransform(QTransform::fromTranslate(0, rowHeight * currentRow)); + rectangle->setBackgroundBrush(backgroundBrushes[currentRow % backgroundBrushes.size()]); + + auto *point = (*theGraph)[currentVertex].point.get(); + point->setRect(0.0, 0.0, pointSize, pointSize); + point->setTransform(QTransform::fromTranslate(pointSpacing * currentColumn, + rowHeight * currentRow + rowHeight / 2.0 - pointSize / 2.0)); + point->setBrush(currentBrush); + + float cheat = 0.0; + if (direction == -1) + cheat = rowHeight; + + auto *visiblePixmap = (*theGraph)[currentVertex].visibleIcon.get(); + visiblePixmap->setTransform(QTransform::fromTranslate(0.0, rowHeight * currentRow + cheat)); //calculate x location later. + + auto *statePixmap = (*theGraph)[currentVertex].stateIcon.get(); + statePixmap->setTransform(QTransform::fromTranslate(0.0, rowHeight * currentRow + cheat)); //calculate x location later. + + auto *pixmap = (*theGraph)[currentVertex].icon.get(); + pixmap->setTransform(QTransform::fromTranslate(0.0, rowHeight * currentRow + cheat)); //calculate x location later. + + auto *text = (*theGraph)[currentVertex].text.get(); + text->setPlainText(QString::fromUtf8(findRecord(currentVertex, *graphLink).DObject->Label.getValue())); + text->setDefaultTextColor(currentBrush.color()); + maxTextLength = std::max(maxTextLength, static_cast(text->boundingRect().width())); + text->setTransform(QTransform::fromTranslate + (0.0, rowHeight * currentRow - verticalSpacing * 2.0 + cheat)); //calculate x location later. + (*theGraph)[currentVertex].lastVisibleState = VisibilityState::None; //force visual update for color. + + //store column and row int the graph. use for connectors later. + (*theGraph)[currentVertex].row = currentRow; + (*theGraph)[currentVertex].column.reset().set((currentColumn)); + + //our list is topo sorted so all dependents should be located, so we can build the connectors. + //will have some more logic for connector path, simple for now. + float currentX = pointSpacing * currentColumn + pointSize / 2.0; + float currentY = rowHeight * currentRow + rowHeight / 2.0; + OutEdgeIterator it, itEnd; + boost::tie(it, itEnd) = boost::out_edges(currentVertex, *theGraph); + for (; it != itEnd; ++it) + { + Vertex target = boost::target(*it, *theGraph); + if (!(*theGraph)[target].dagVisible) + continue; //we don't make it here if source isn't visible. So don't have to worry about that. + float dependentX = pointSpacing * static_cast(std::log2((*theGraph)[target].column.to_ulong())) + pointSize / 2.0; //on center. + float dependentY = rowHeight * (*theGraph)[target].row + rowHeight / 2.0; + + QGraphicsPathItem *pathItem = (*theGraph)[*it].connector.get(); + pathItem->setBrush(Qt::NoBrush); + QPainterPath path; + path.moveTo(currentX, currentY); + if (currentColumn == static_cast(std::log2((*theGraph)[target].column.to_ulong()))) + path.lineTo(currentX, dependentY); //straight connector in y. + else + { + //connector with bend. + float radius = pointSpacing / 1.9; //no zero length line. + + path.lineTo(currentX, dependentY + radius * direction); + + float yPosition; + if (direction == -1.0) + yPosition = dependentY - 2.0 * radius; + else + yPosition = dependentY; + float width = 2.0 * radius; + float height = width; + if (dependentX > currentX) //radius to the right. + { + QRectF arcRect(currentX, yPosition, width, height); + path.arcTo(arcRect, 180.0, 90.0 * -direction); + } + else //radius to the left. + { + QRectF arcRect(currentX - 2.0 * radius, yPosition, width, height); + path.arcTo(arcRect, 0.0, 90.0 * direction); + } + path.lineTo(dependentX, dependentY); + } + pathItem->setPath(path); + } + + currentRow++; + } + + //now that we have the graph drawn we know where to place icons and text. + float columnSpacing = (maxColumn * pointSpacing); + for (const auto ¤tVertex : sorted) + { + float localCurrentX = columnSpacing; + localCurrentX += pointToIcon; + auto *visiblePixmap = (*theGraph)[currentVertex].visibleIcon.get(); + QTransform visibleIconTransform = QTransform::fromTranslate(localCurrentX, 0.0); + visiblePixmap->setTransform(visiblePixmap->transform() * visibleIconTransform); + + localCurrentX += iconSize + iconToIcon; + auto *statePixmap = (*theGraph)[currentVertex].stateIcon.get(); + QTransform stateIconTransform = QTransform::fromTranslate(localCurrentX, 0.0); + statePixmap->setTransform(statePixmap->transform() * stateIconTransform); + + localCurrentX += iconSize + iconToIcon; + auto *pixmap = (*theGraph)[currentVertex].icon.get(); + QTransform iconTransform = QTransform::fromTranslate(localCurrentX, 0.0); + pixmap->setTransform(pixmap->transform() * iconTransform); + + localCurrentX += iconSize + iconToText; + auto *text = (*theGraph)[currentVertex].text.get(); + QTransform textTransform = QTransform::fromTranslate(localCurrentX, 0.0); + text->setTransform(text->transform() * textTransform); + + auto *rectangle = (*theGraph)[currentVertex].rectangle.get(); + QRectF rect = rectangle->rect(); + rect.setWidth(localCurrentX + maxTextLength + 2.0 * rowPadding); + rectangle->setRect(rect); + } + + //Modeling_Challenge_Casting_ta4 with 59 features: "Initialize DAG View time: 0.007" + //keeping algo simple with extra loops only added 0.002 to above number. +// std::cout << "Initialize DAG View time: " << Base::TimeInfo::diffTimeF(startTime, Base::TimeInfo()) << std::endl; + +// outputGraphviz(*theGraph, "./graphviz.dot"); + graphDirty = false; +} + +void Model::indexVerticesEdges() +{ + std::size_t index = 0; + + //index vertices. + VertexIterator it, itEnd; + for(boost::tie(it, itEnd) = boost::vertices(*theGraph); it != itEnd; ++it) + { + boost::put(boost::vertex_index, *theGraph, *it, index); + index++; + } + + //index edges. didn't need this when I put it in. + EdgeIterator eit, eitEnd; + index = 0; + for(boost::tie(eit, eitEnd) = boost::edges(*theGraph); eit != eitEnd; ++eit) + { + boost::put(boost::edge_index, *theGraph, *eit, index); + index++; + } +} + +void Model::removeAllItems() +{ + if (theGraph) + { + BGL_FORALL_VERTICES(currentVertex, *theGraph, Graph) + removeVertexItemsFromScene(currentVertex); + + BGL_FORALL_EDGES(currentEdge, *theGraph, Graph) + { + if ((*theGraph)[currentEdge].connector->scene()) + this->removeItem((*theGraph)[currentEdge].connector.get()); + } + } +} + +void Model::addVertexItemsToScene(const Gui::DAG::Vertex& vertexIn) +{ + //these are either all in or all out. so just test rectangle. + if ((*theGraph)[vertexIn].rectangle->scene()) //already in the scene. + return; + this->addItem((*theGraph)[vertexIn].rectangle.get()); + this->addItem((*theGraph)[vertexIn].point.get()); + this->addItem((*theGraph)[vertexIn].visibleIcon.get()); + this->addItem((*theGraph)[vertexIn].stateIcon.get()); + this->addItem((*theGraph)[vertexIn].icon.get()); + this->addItem((*theGraph)[vertexIn].text.get()); +} + +void Model::removeVertexItemsFromScene(const Gui::DAG::Vertex& vertexIn) +{ + //these are either all in or all out. so just test rectangle. + if (!(*theGraph)[vertexIn].rectangle->scene()) //not in the scene. + return; + this->removeItem((*theGraph)[vertexIn].rectangle.get()); + this->removeItem((*theGraph)[vertexIn].point.get()); + this->removeItem((*theGraph)[vertexIn].visibleIcon.get()); + this->removeItem((*theGraph)[vertexIn].stateIcon.get()); + this->removeItem((*theGraph)[vertexIn].text.get()); + this->removeItem((*theGraph)[vertexIn].icon.get()); +} + +void Model::updateStates() +{ + //not sure I want to use the same pixmap merge for failing feature icons. + //thinking maybe red background or another column of icons for state? + + BGL_FORALL_VERTICES(currentVertex, *theGraph, Graph) + { + const GraphLinkRecord &record = findRecord(currentVertex, *graphLink); + + auto *visiblePixmap = (*theGraph)[currentVertex].visibleIcon.get(); + VisibilityState currentVisibilityState = (record.VPDObject->isShow()) ? (VisibilityState::On) : (VisibilityState::Off); + if + ( + (currentVisibilityState != (*theGraph)[currentVertex].lastVisibleState) || + ((*theGraph)[currentVertex].lastVisibleState == VisibilityState::None) + ) + { + if (record.VPDObject->isShow()) + visiblePixmap->setPixmap(visiblePixmapEnabled); + else + visiblePixmap->setPixmap(visiblePixmapDisabled); + (*theGraph)[currentVertex].lastVisibleState = currentVisibilityState; + } + + FeatureState currentFeatureState = FeatureState::Pass; + if (record.DObject->isError()) + currentFeatureState = FeatureState::Fail; + else if ((record.DObject->mustExecute() == 1)) + currentFeatureState = FeatureState::Pending; + if (currentFeatureState != (*theGraph)[currentVertex].lastFeatureState) + { + if (currentFeatureState == FeatureState::Pass) + { + (*theGraph)[currentVertex].stateIcon->setPixmap(passPixmap); + } + else + { + if (currentFeatureState == FeatureState::Fail) + (*theGraph)[currentVertex].stateIcon->setPixmap(failPixmap); + else + (*theGraph)[currentVertex].stateIcon->setPixmap(pendingPixmap); + } + (*theGraph)[currentVertex].stateIcon->setToolTip(QString::fromAscii(record.DObject->getStatusString())); + (*theGraph)[currentVertex].lastFeatureState = currentFeatureState; + } + } +} + +RectItem* Model::getRectFromPosition(const QPointF& position) +{ + RectItem *rect = nullptr; + auto theItems = this->items(position, Qt::IntersectsItemBoundingRect, Qt::DescendingOrder); + for (auto *currentItem : theItems) + { + rect = dynamic_cast(currentItem); + if (rect) break; + } + + return rect; +} + +void Model::mouseMoveEvent(QGraphicsSceneMouseEvent* event) +{ + auto clearPrehighlight = [this]() + { + if (currentPrehighlight) + { + currentPrehighlight->preHighlightOff(); + currentPrehighlight = nullptr; + } + }; + + RectItem *rect = getRectFromPosition(event->scenePos()); + if (!rect) + { + clearPrehighlight(); + return; + } + + if (rect == currentPrehighlight) + return; + + clearPrehighlight(); + rect->preHighlightOn(); + currentPrehighlight = rect; + invalidate(); + + QGraphicsScene::mouseMoveEvent(event); +} + +void Model::mousePressEvent(QGraphicsSceneMouseEvent* event) +{ + auto goShiftSelect = [this, event]() + { + QPointF currentPickPoint = event->scenePos(); + QGraphicsLineItem intersectionLine(QLineF(lastPick, currentPickPoint)); + QListselection = collidingItems(&intersectionLine); + for (auto currentItem = selection.begin(); currentItem != selection.end(); ++currentItem) + { + RectItem *rect = dynamic_cast(*currentItem); + if (!rect) continue; + const GraphLinkRecord &selectionRecord = findRecord(rect, *graphLink); + Gui::Selection().addSelection(selectionRecord.DObject->getDocument()->getName(), + selectionRecord.DObject->getNameInDocument()); + } + }; + + auto toggleSelect = [](const App::DocumentObject *dObjectIn, RectItem *rectIn) + { + if (rectIn->isSelected()) + Gui::Selection().rmvSelection(dObjectIn->getDocument()->getName(), dObjectIn->getNameInDocument()); + else + Gui::Selection().addSelection(dObjectIn->getDocument()->getName(), dObjectIn->getNameInDocument()); + }; + + if (proxy) + renameAcceptedSlot(); + + if (event->button() == Qt::LeftButton) + { + RectItem *rect = getRectFromPosition(event->scenePos()); + if (rect) + { + const GraphLinkRecord &record = findRecord(rect, *graphLink); + + //don't like that I am doing this again here after getRectFromPosition call. + QGraphicsItem *item = itemAt(event->scenePos()); + QGraphicsPixmapItem *pixmapItem = dynamic_cast(item); + if (pixmapItem && (pixmapItem == (*theGraph)[record.vertex].visibleIcon.get())) + { + //get all selections, but for now just the current pick. + if ((*theGraph)[record.vertex].lastVisibleState == VisibilityState::Off) + const_cast(record.VPDObject)->show(); //const hack + else + const_cast(record.VPDObject)->hide(); //const hack + + return; + } + + const App::DocumentObject *dObject = record.DObject; + if (selectionMode == SelectionMode::Single) + { + if (event->modifiers() & Qt::ControlModifier) + { + toggleSelect(dObject, rect); + } + else if((event->modifiers() & Qt::ShiftModifier) && lastPickValid) + { + goShiftSelect(); + } + else + { + Gui::Selection().clearSelection(dObject->getDocument()->getName()); + Gui::Selection().addSelection(dObject->getDocument()->getName(), dObject->getNameInDocument()); + } + } + if (selectionMode == SelectionMode::Multiple) + { + if((event->modifiers() & Qt::ShiftModifier) && lastPickValid) + { + goShiftSelect(); + } + else + { + toggleSelect(dObject, rect); + } + } + lastPickValid = true; + lastPick = event->scenePos(); + } + else + { + lastPickValid = false; + Gui::Selection().clearSelection(); //get document name? + } + } + + QGraphicsScene::mousePressEvent(event); +} + +void Model::mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) +{ + if (event->button() == Qt::LeftButton) + { + auto selections = getAllSelected(); + if(selections.size() != 1) + return; + const GraphLinkRecord &record = findRecord(selections.front(), *graphLink); + Gui::Document* doc = Gui::Application::Instance->getDocument(record.DObject->getDocument()); + MDIView *view = doc->getActiveView(); + if (view) + getMainWindow()->setActiveWindow(view); + const_cast(record.VPDObject)->doubleClicked(); + } + + QGraphicsScene::mouseDoubleClickEvent(event); +} + + +std::vector Model::getAllSelected() +{ + std::vector out; + + BGL_FORALL_VERTICES(currentVertex, *theGraph, Graph) + { + if ((*theGraph)[currentVertex].rectangle->isSelected()) + out.push_back(currentVertex); + } + + return out; +} + +void Model::contextMenuEvent(QGraphicsSceneContextMenuEvent* event) +{ + RectItem *rect = getRectFromPosition(event->scenePos()); + if (rect) + { + const GraphLinkRecord &record = findRecord(rect, *graphLink); + + //don't like that I am doing this again here after getRectFromPosition call. + QGraphicsItem *item = itemAt(event->scenePos()); + QGraphicsPixmapItem *pixmapItem = dynamic_cast(item); + if (pixmapItem && (pixmapItem == (*theGraph)[record.vertex].visibleIcon.get())) + { + visiblyIsolate(record.vertex); + return; + } + + if (!rect->isSelected()) + { + Gui::Selection().clearSelection(record.DObject->getDocument()->getName()); + Gui::Selection().addSelection(record.DObject->getDocument()->getName(), record.DObject->getNameInDocument()); + lastPickValid = true; + lastPick = event->scenePos(); + } + + MenuItem view; + Gui::Application::Instance->setupContextMenu("Tree", &view); + QMenu contextMenu; + MenuManager::getInstance()->setupContextMenu(&view, contextMenu); + + //actions for only one selection. + std::vector selections = getAllSelected(); + if (selections.size() == 1) + { + contextMenu.addAction(renameAction); + //when we have only one selection then we know it is rect from above. + if (!rect->isEditing()) + const_cast(record.VPDObject)->setupContextMenu + (&contextMenu, this, SLOT(editingStartSlot())); //const hack. + else + contextMenu.addAction(editingFinishedAction); + } + + if (contextMenu.actions().count() > 0) + contextMenu.exec(event->screenPos()); + } + + QGraphicsScene::contextMenuEvent(event); +} + +void Model::onRenameSlot() +{ + assert(proxy == nullptr); + std::vector selections = getAllSelected(); + assert(selections.size() == 1); + + LineEdit *lineEdit = new LineEdit(); + auto *text = (*theGraph)[selections.front()].text.get(); + lineEdit->setText(text->toPlainText()); + connect(lineEdit, SIGNAL(acceptedSignal()), this, SLOT(renameAcceptedSlot())); + connect(lineEdit, SIGNAL(rejectedSignal()), this, SLOT(renameRejectedSlot())); + + proxy = this->addWidget(lineEdit); + proxy->setGeometry(text->sceneBoundingRect()); + + lineEdit->selectAll(); + QTimer::singleShot(0, lineEdit, SLOT(setFocus())); +} + +void Model::renameAcceptedSlot() +{ + assert(proxy); + + std::vector selections = getAllSelected(); + assert(selections.size() == 1); + const GraphLinkRecord &record = findRecord(selections.front(), *graphLink); + + LineEdit *lineEdit = dynamic_cast(proxy->widget()); + assert(lineEdit); + const_cast(record.DObject)->Label.setValue(lineEdit->text().toUtf8().constData()); //const hack + + finishRename(); +} + +void Model::renameRejectedSlot() +{ + finishRename(); +} + +void Model::finishRename() +{ + assert(proxy); + this->removeItem(proxy); + proxy->deleteLater(); + proxy = nullptr; + this->invalidate(); +} + +void Model::editingStartSlot() +{ + QAction* action = qobject_cast(sender()); + if (action) + { + int edit = action->data().toInt(); + auto selections = getAllSelected(); + assert(selections.size() == 1); + const GraphLinkRecord &record = findRecord(selections.front(), *graphLink); + Gui::Document* doc = Gui::Application::Instance->getDocument(record.DObject->getDocument()); + MDIView *view = doc->getActiveView(); + if (view) + getMainWindow()->setActiveWindow(view); + doc->setEdit(const_cast(record.VPDObject), edit); + } +} + +void Model::editingFinishedSlot() +{ + auto selections = getAllSelected(); + assert(selections.size() == 1); + const GraphLinkRecord &record = findRecord(selections.front(), *graphLink); + Gui::Document* doc = Gui::Application::Instance->getDocument(record.DObject->getDocument()); + doc->commitCommand(); + doc->resetEdit(); + doc->getDocument()->recompute(); +} + +void Model::visiblyIsolate(Gui::DAG::Vertex sourceIn) +{ + auto buildSkipTypes = []() + { + std::vector out; + Base::Type type; + type = Base::Type::fromName("App::DocumentObjectGroup"); + if (type != Base::Type::badType()) out.push_back(type); + type = Base::Type::fromName("App::Part"); + if (type != Base::Type::badType()) out.push_back(type); + type = Base::Type::fromName("PartDesign::Body"); + if (type != Base::Type::badType()) out.push_back(type); + + return out; + }; + + auto testSkipType = [](const App::DocumentObject *dObject, const std::vector &types) + { + for (const auto ¤tType : types) + { + if (dObject->isDerivedFrom(currentType)) + return true; + } + return false; + }; + + indexVerticesEdges(); + Path connectedVertices; + ConnectionVisitor visitor(connectedVertices); + boost::breadth_first_search(*theGraph, sourceIn, boost::visitor(visitor)); + boost::breadth_first_search(boost::make_reverse_graph(*theGraph), sourceIn, boost::visitor(visitor)); + + //note source vertex is added twice to Path. Once for each search. + static std::vector skipTypes = buildSkipTypes(); + for (const auto ¤tVertex : connectedVertices) + { + const GraphLinkRecord &record = findRecord(currentVertex, *graphLink); + if (testSkipType(record.DObject, skipTypes)) + continue; + const_cast(record.VPDObject)->hide(); //const hack + } + + const GraphLinkRecord &sourceRecord = findRecord(sourceIn, *graphLink); + if (!testSkipType(sourceRecord.DObject, skipTypes)) + const_cast(sourceRecord.VPDObject)->show(); //const hack +} + + +#include diff --git a/src/Gui/DAGView/DAGModel.h b/src/Gui/DAGView/DAGModel.h new file mode 100644 index 000000000..635ca87fe --- /dev/null +++ b/src/Gui/DAGView/DAGModel.h @@ -0,0 +1,167 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef DAGMODEL_H +#define DAGMODEL_H + +#include +#include + +#include + +#include +#include +#include + +#include "DAGRectItem.h" +#include "DAGModelGraph.h" +#include "DAGFilter.h" + +class QGraphicsSceneHoverEvent; +class QGraphicsProxyWidget; + +namespace Gui +{ + class Document; + class ViewProviderDocumentObject; + class SelectionChanges; + + namespace DAG + { + class LineEdit : public QLineEdit + { + Q_OBJECT + public: + LineEdit(QWidget *parentIn = 0); + Q_SIGNALS: + void acceptedSignal(); + void rejectedSignal(); + protected: + virtual void keyPressEvent(QKeyEvent*); + }; + + class Model : public QGraphicsScene + { + Q_OBJECT + public: + Model(QObject *parentIn, const Gui::Document &documentIn); + virtual ~Model() override; + void awake(); //!< hooked up to event dispatcher for update when idle. + void selectionChanged(const SelectionChanges& msg); + + protected: + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event) override; + virtual void mousePressEvent(QGraphicsSceneMouseEvent* event) override; + virtual void mouseDoubleClickEvent(QGraphicsSceneMouseEvent* event) override; + virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override; + + private Q_SLOTS: + void updateSlot(); + void onRenameSlot(); + void renameAcceptedSlot(); + void renameRejectedSlot(); + void editingStartSlot(); + void editingFinishedSlot(); + + private: + Model(){} + //documentObject slots. + typedef boost::BOOST_SIGNALS_NAMESPACE::connection Connection; + Connection connectNewObject; + Connection connectDelObject; + Connection connectChgObject; + Connection connectRenObject; + Connection connectActObject; + Connection connectEdtObject; + Connection connectResObject; + Connection connectHltObject; + Connection connectExpObject; + void slotNewObject(const Gui::ViewProviderDocumentObject &VPDObjectIn); + void slotDeleteObject(const Gui::ViewProviderDocumentObject &VPDObjectIn); + void slotChangeObject(const Gui::ViewProviderDocumentObject &VPDObjectIn, const App::Property& propertyIn); + void slotInEdit(const Gui::ViewProviderDocumentObject &VPDObjectIn); + void slotResetEdit(const Gui::ViewProviderDocumentObject &VPDObjectIn); + + std::shared_ptr graphLink; + std::shared_ptr theGraph; + bool graphDirty; + + void indexVerticesEdges(); + void removeAllItems(); + void addVertexItemsToScene(const Vertex &vertexIn); + void removeVertexItemsFromScene(const Vertex &vertexIn); + void updateStates(); + + RectItem* getRectFromPosition(const QPointF &position); //!< can be nullptr + + //! @name View Constants for spacing + //@{ + float fontHeight; //!< height of the current qApp default font. + float direction; //!< controls top to bottom or bottom to top direction. + float verticalSpacing; //!< pixels between top and bottom of text to background rectangle. + float rowHeight; //!< height of background rectangle. + float iconSize; //!< size of icon to match font. + float pointSize; //!< size of the connection point. + float pointSpacing; //!< spacing between pofloat columns. + float pointToIcon; //!< spacing from last column points to first icon. + float iconToIcon; //!< spacing between icons. + float iconToText; //!< spacing between last icon and text. + float rowPadding; //!< spaces added to rectangle bacground width ends. + std::vector backgroundBrushes; //!< brushes to paint background rectangles. + std::vector forgroundBrushes; //!< brushes to paint points, connectors, text. + void setupViewConstants(); + //@} + + RectItem *currentPrehighlight; + + enum class SelectionMode + { + Single, + Multiple + }; + SelectionMode selectionMode; + std::vector getAllSelected(); + void visiblyIsolate(Vertex sourceIn); //!< hide any connected feature and turn on sourceIn. + + QPointF lastPick; + bool lastPickValid = false; + + QPixmap visiblePixmapEnabled; + QPixmap visiblePixmapDisabled; + QPixmap passPixmap; + QPixmap failPixmap; + QPixmap pendingPixmap; + + QAction *renameAction; + QAction *editingFinishedAction; + QGraphicsProxyWidget *proxy = nullptr; + void finishRename(); + + //filters + void setupFilters(); + typedef std::vector > FilterContainer; + FilterContainer filters; + }; + } +} + +#endif // DAGMODEL_H diff --git a/src/Gui/DAGView/DAGModelGraph.cpp b/src/Gui/DAGView/DAGModelGraph.cpp new file mode 100644 index 000000000..944d22df6 --- /dev/null +++ b/src/Gui/DAGView/DAGModelGraph.cpp @@ -0,0 +1,110 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#endif + +#include "DAGModelGraph.h" + +using namespace Gui; +using namespace DAG; + +VertexProperty::VertexProperty() : + rectangle(new RectItem()), + point(new QGraphicsEllipseItem()), + visibleIcon(new QGraphicsPixmapItem()), + stateIcon(new QGraphicsPixmapItem()), + icon(new QGraphicsPixmapItem()), + text(new QGraphicsTextItem()), + row(0), + column(0), + lastVisibleState(VisibilityState::None), + dagVisible(true) +{ + //set z values. + this->rectangle->setZValue(-1000.0); + this->point->setZValue(1000.0); + this->visibleIcon->setZValue(0.0); + this->stateIcon->setZValue(0.0); + this->icon->setZValue(0.0); + this->text->setZValue(0.0); +} + +EdgeProperty::EdgeProperty() : relation(BranchTag::None) +{ + +} + +const GraphLinkRecord& Gui::DAG::findRecord(Vertex vertexIn, const GraphLinkContainer &containerIn) +{ + typedef GraphLinkContainer::index::type List; + const List &list = containerIn.get(); + List::const_iterator it = list.find(vertexIn); + assert(it != list.end()); + return *it; +} + +const GraphLinkRecord& Gui::DAG::findRecord(const App::DocumentObject* dObjectIn, const GraphLinkContainer &containerIn) +{ + typedef GraphLinkContainer::index::type List; + const List &list = containerIn.get(); + List::const_iterator it = list.find(dObjectIn); + assert(it != list.end()); + return *it; +} + +const GraphLinkRecord& Gui::DAG::findRecord(const ViewProviderDocumentObject* VPDObjectIn, const GraphLinkContainer &containerIn) +{ + typedef GraphLinkContainer::index::type List; + const List &list = containerIn.get(); + List::const_iterator it = list.find(VPDObjectIn); + assert(it != list.end()); + return *it; +} + +const GraphLinkRecord& Gui::DAG::findRecord(const RectItem* rectIn, const GraphLinkContainer &containerIn) +{ + typedef GraphLinkContainer::index::type List; + const List &list = containerIn.get(); + List::const_iterator it = list.find(rectIn); + assert(it != list.end()); + return *it; +} + +const GraphLinkRecord& Gui::DAG::findRecord(const std::string &stringIn, const GraphLinkContainer &containerIn) +{ + typedef GraphLinkContainer::index::type List; + const List &list = containerIn.get(); + List::const_iterator it = list.find(stringIn); + assert(it != list.end()); + return *it; +} + +void Gui::DAG::eraseRecord(const ViewProviderDocumentObject* VPDObjectIn, GraphLinkContainer &containerIn) +{ + typedef GraphLinkContainer::index::type List; + const List &list = containerIn.get(); + List::iterator it = list.find(VPDObjectIn); + assert(it != list.end()); + containerIn.get().erase(it); +} \ No newline at end of file diff --git a/src/Gui/DAGView/DAGModelGraph.h b/src/Gui/DAGView/DAGModelGraph.h new file mode 100644 index 000000000..894c6c284 --- /dev/null +++ b/src/Gui/DAGView/DAGModelGraph.h @@ -0,0 +1,291 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef DAGMODELGRAPH_H +#define DAGMODELGRAPH_H + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "DAGRectItem.h" + +namespace App{class DocumentObject;} + +namespace Gui +{ + class ViewProviderDocumentObject; + + namespace DAG + { + enum class VisibilityState + { + None = 0, // ColumnMask; + + /*! @brief Graph vertex information + * + * My data stored for each vertex; + */ + struct VertexProperty + { + VertexProperty(); + std::shared_ptr rectangle; //!< background + std::shared_ptr point; //!< point + std::shared_ptr visibleIcon; //!< visible Icon + std::shared_ptr stateIcon; //!< visible Icon + std::shared_ptr icon; //!< icon + std::shared_ptr text; //!< text + int row; //!< row for this entry. + ColumnMask column; //!< column number containing the point. + int topoSortIndex; + VisibilityState lastVisibleState; //!< visibility test. + FeatureState lastFeatureState; //!< feature state test. + bool dagVisible; //!< should entry be visible in the DAG view. + }; + /*! @brief boost data for each vertex. + * + * needed to create an internal index for vertex. needed for listS. + * color is needed by some algorithms */ + typedef boost::property + < + boost::vertex_index_t, std::size_t, + boost::property + > vertex_prop; + + /*! @brief Graph edge information + * + * My data stored for each edge; + */ + struct EdgeProperty + { + //! Feature relation meta data. Not used right now. + enum class BranchTag + { + None = 0, //!< not defined. + Create, //!< create a new branch. + Continue, //!< continue a branch. + Terminate //!< terminate a branch. + }; + EdgeProperty(); + BranchTag relation; + std::shared_ptr connector; //!< line representing link between nodes. + }; + /*! @brief needed to create an internal index for graph edges. needed for setS.*/ + typedef boost::property edge_prop; + + typedef boost::adjacency_list Graph; + typedef boost::graph_traits::vertex_descriptor Vertex; + typedef boost::graph_traits::edge_descriptor Edge; + typedef boost::graph_traits::vertex_iterator VertexIterator; + typedef boost::graph_traits::edge_iterator EdgeIterator; + typedef boost::graph_traits::in_edge_iterator InEdgeIterator; + typedef boost::graph_traits::out_edge_iterator OutEdgeIterator; + typedef boost::graph_traits::adjacency_iterator VertexAdjacencyIterator; + typedef boost::reverse_graph GraphReversed; + typedef std::vector Path; //!< a path or any array of vertices + + template + class Edge_writer { + public: + Edge_writer(const GraphEW &graphEWIn) : graphEW(graphEWIn) {} + template + void operator()(std::ostream& out, const EdgeW& edgeW) const + { + out << "[label=\""; + out << "edge"; + out << "\"]"; + } + private: + const GraphEW &graphEW; + }; + + template + class Vertex_writer { + public: + Vertex_writer(const GraphVW &graphVWIn) : graphVW(graphVWIn) {} + template + void operator()(std::ostream& out, const VertexW& vertexW) const + { + out << "[label=\""; + out << graphVW[vertexW].text->toPlainText().toAscii().data(); + out << "\"]"; + } + private: + const GraphVW &graphVW; + }; + + template + void outputGraphviz(const GraphIn &graphIn, const std::string &filePath) + { + std::ofstream file(filePath.c_str()); + boost::write_graphviz(file, graphIn, Vertex_writer(graphIn), + Edge_writer(graphIn)); + } + + //! get all the leaves of the templated graph. Not used right now. + template + class RakeLeaves + { + typedef boost::graph_traits::vertex_descriptor GraphInVertex; + typedef std::vector GraphInVertices; + public: + RakeLeaves(const GraphIn &graphIn) : graph(graphIn) {} + GraphInVertices operator()() const + { + GraphInVertices out; + BGL_FORALL_VERTICES_T(currentVertex, graph, GraphIn) + { + if (boost::out_degree(currentVertex, graph) == 0) + out.push_back(currentVertex); + } + return out; + } + private: + const GraphIn &graph; + }; + + //! get all the roots of the templated graph. Not used right now. + template + class DigRoots + { + typedef boost::graph_traits::vertex_descriptor GraphInVertex; + typedef std::vector GraphInVertices; + public: + DigRoots(const GraphIn &graphIn) : graph(graphIn) {} + GraphInVertices operator()() const + { + GraphInVertices out; + BGL_FORALL_VERTICES_T(currentVertex, graph, GraphIn) + { + if (boost::in_degree(currentVertex, graph) == 0) + out.push_back(currentVertex); + } + return out; + } + private: + const GraphIn &graph; + }; + + /*! @brief Get connected components. + */ + class ConnectionVisitor : public boost::default_bfs_visitor + { + public: + ConnectionVisitor(std::vector &verticesIn) : vertices(verticesIn){} + + template + void discover_vertex(TVertex vertex, TGraph &graph) + { + vertices.push_back(vertex); + } + private: + std::vector &vertices; + }; + + /*! Multi_index record. */ + struct GraphLinkRecord + { + const App::DocumentObject *DObject; //!< document object + const Gui::ViewProviderDocumentObject *VPDObject; //!< view provider + const RectItem *rectItem; //!< qgraphics item. + std::string uniqueName; //!< name for document object. + Vertex vertex; //!< vertex in graph. + + //@{ + //! used as tags. + struct ByDObject{}; + struct ByVPDObject{}; + struct ByRectItem{}; + struct ByUniqueName{}; + struct ByVertex{}; + //@} + }; + + namespace BMI = boost::multi_index; + typedef boost::multi_index_container + < + GraphLinkRecord, + BMI::indexed_by + < + BMI::ordered_unique + < + BMI::tag, + BMI::member + >, + BMI::ordered_unique + < + BMI::tag, + BMI::member + >, + BMI::ordered_unique + < + BMI::tag, + BMI::member + >, + BMI::ordered_unique + < + BMI::tag, + BMI::member + >, + BMI::ordered_unique + < + BMI::tag, + BMI::member + > + > + > GraphLinkContainer; + + const GraphLinkRecord& findRecord(Vertex vertexIn, const GraphLinkContainer &containerIn); + const GraphLinkRecord& findRecord(const App::DocumentObject* dObjectIn, const GraphLinkContainer &containerIn); + const GraphLinkRecord& findRecord(const Gui::ViewProviderDocumentObject* VPDObjectIn, const GraphLinkContainer &containerIn); + const GraphLinkRecord& findRecord(const RectItem* rectIn, const GraphLinkContainer &containerIn); + const GraphLinkRecord& findRecord(const std::string &stringIn, const GraphLinkContainer &containerIn); + void eraseRecord(const Gui::ViewProviderDocumentObject* VPDObjectIn, GraphLinkContainer &containerIn); + } +} + +#endif // DAGMODELGRAPH_H diff --git a/src/Gui/DAGView/DAGRectItem.cpp b/src/Gui/DAGView/DAGRectItem.cpp new file mode 100644 index 000000000..51bbd3376 --- /dev/null +++ b/src/Gui/DAGView/DAGRectItem.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#include +#include +#endif + +#include + +#include "DAGRectItem.h" + +using namespace Gui; +using namespace DAG; + +RectItem::RectItem(QGraphicsItem* parent) : QGraphicsRectItem(parent) +{ + selected = false; + preSelected = false; + editing = false; +} + +void RectItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) +{ + painter->save(); + + QStyleOptionViewItemV4 styleOption; + + styleOption.backgroundBrush = backgroundBrush; + if (editing) + styleOption.backgroundBrush = editBrush; + else + { + styleOption.state |= QStyle::State_Enabled; + if (selected) + styleOption.state |= QStyle::State_Selected; + if (preSelected) + { + if (!selected) + { + styleOption.state |= QStyle::State_Selected; + QPalette palette = styleOption.palette; + QColor tempColor = palette.color(QPalette::Active, QPalette::Highlight); + tempColor.setAlphaF(0.15); + palette.setColor(QPalette::Inactive, QPalette::Highlight, tempColor); + styleOption.palette = palette; + } + styleOption.state |= QStyle::State_MouseOver; + } + } + styleOption.rect = this->rect().toRect(); + + QApplication::style()->drawControl(QStyle::CE_ItemViewItem, &styleOption, painter); + + painter->restore(); +} + +#include diff --git a/src/Gui/DAGView/DAGRectItem.h b/src/Gui/DAGView/DAGRectItem.h new file mode 100644 index 000000000..4d70c11b0 --- /dev/null +++ b/src/Gui/DAGView/DAGRectItem.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef DAGRECTITEM_H +#define DAGRECTITEM_H + +#include +#include + +namespace Gui +{ + namespace DAG + { + /*all right I give up! the parenting combined with the zvalues is fubar! + * you can't control any kind of layering between children of separate parents + */ + class RectItem : public QGraphicsRectItem + { + public: + RectItem(QGraphicsItem* parent = 0); + void setBackgroundBrush(const QBrush &brushIn){backgroundBrush = brushIn;} + void setEditingBrush(const QBrush &brushIn){editBrush = brushIn;} + void preHighlightOn(){preSelected = true;} + void preHighlightOff(){preSelected = false;} + void selectionOn(){selected = true;} + void selectionOff(){selected = false;} + bool isSelected(){return selected;} + bool isPreSelected(){return preSelected;} + void editingStart(){editing = true;} + void editingFinished(){editing = false;} + bool isEditing(){return editing;} + protected: + virtual void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0); + private: + QBrush backgroundBrush; //!< brush used for background. not used yet. + QBrush editBrush; //!< brush used when object is in edit mode. + //start with booleans, may expand to state. + bool selected; + bool preSelected; + bool editing; + }; + } +} + +#endif // DAGRECTITEM_H diff --git a/src/Gui/DAGView/DAGView.cpp b/src/Gui/DAGView/DAGView.cpp new file mode 100644 index 000000000..932f71218 --- /dev/null +++ b/src/Gui/DAGView/DAGView.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#include +#include +#endif + +#include + +#include + +#include +#include +#include + +#include "DAGModel.h" +#include "DAGView.h" + +using namespace Gui; +using namespace DAG; + +DAG::DockWindow::DockWindow(Gui::Document* gDocumentIn, QWidget* parent): Gui::DockWindow(gDocumentIn, parent) +{ + dagView = new View(this); + QVBoxLayout *layout = new QVBoxLayout(); + layout->addWidget(dagView); + this->setLayout(layout); +} + +View::View(QWidget* parentIn): QGraphicsView(parentIn) +{ + this->setRenderHint(QPainter::Antialiasing, true); + this->setRenderHint(QPainter::TextAntialiasing, true); + Application::Instance->signalActiveDocument.connect(boost::bind(&View::slotActiveDocument, this, _1)); + Application::Instance->signalDeleteDocument.connect(boost::bind(&View::slotDeleteDocument, this, _1)); + + //just update the dagview when the gui process is idle. + connect(QAbstractEventDispatcher::instance(), SIGNAL(awake()), this, SLOT(awakeSlot())); +} + +View::~View() +{ + Application::Instance->signalActiveDocument.disconnect(boost::bind(&View::slotActiveDocument, this, _1)); + Application::Instance->signalDeleteDocument.disconnect(boost::bind(&View::slotDeleteDocument, this, _1)); +} + +void View::slotActiveDocument(const Document &documentIn) +{ + ModelMap::const_iterator it = modelMap.find(&documentIn); + if (it == modelMap.end()) + { + ModelMap::value_type entry(std::make_pair(&documentIn, std::shared_ptr(new Model(this, documentIn)))); + modelMap.insert(entry); + this->setScene(entry.second.get()); + } + else + { + this->setScene(it->second.get()); + } +} + +void View::slotDeleteDocument(const Document &documentIn) +{ + ModelMap::iterator it = modelMap.find(&documentIn); + if (it != modelMap.end()) + modelMap.erase(it); +} + +void View::awakeSlot() +{ + Model *model = dynamic_cast(this->scene()); + if (model) + model->awake(); +} + +void View::onSelectionChanged(const SelectionChanges& msg) +{ + //dispatch to appropriate document. + ModelMap::iterator it; + for (auto it = modelMap.begin(); it != modelMap.end(); ++it) + { + if (std::string(it->first->getDocument()->getName()) == std::string(msg.pDocName)) + { + it->second->selectionChanged(msg); + return; + } + } + + //why am I getting a spontanous event with an empty name? + //also getting events after document has been removed from modelMap. + //just ignore for now. +// std::ostringstream stream; +// stream << std::endl << "couldn't find document of name: " << std::string(msg.pDocName) << std::endl << std::endl; +// Base::Console().Warning(stream.str().c_str()); +// assert(0); //no document of name. +} + + + +#include "moc_DAGView.cpp" diff --git a/src/Gui/DAGView/DAGView.h b/src/Gui/DAGView/DAGView.h new file mode 100644 index 000000000..423dffb08 --- /dev/null +++ b/src/Gui/DAGView/DAGView.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (c) 2015 Thomas Anderson * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef DAGVIEW_H +#define DAGVIEW_H + +#include + +#include + +#include +#include +#include + +#include "DAGModel.h" + +namespace Gui +{ + namespace DAG + { + //! @brief view for DAG viewer + class View : public QGraphicsView, public SelectionObserver + { + Q_OBJECT + public: + View(QWidget *parentIn = 0); + virtual ~View() override; + + public Q_SLOTS: + void awakeSlot(); //!< hooked up to event dispatcher for update when idle. + + private: + virtual void onSelectionChanged(const SelectionChanges& msg) override; + + void slotActiveDocument(const Gui::Document &documentIn); + void slotDeleteDocument(const Gui::Document &documentIn); + + typedef std::map > ModelMap; + ModelMap modelMap; + }; + + //! @brief dock window for DAG viewer + class DockWindow : public Gui::DockWindow + { + Q_OBJECT + public: + DockWindow(Gui::Document* gDocumentIn = 0, QWidget *parent = 0); + ~DockWindow(){}; + + private: + View *dagView; + }; + } +} + +#endif // DAGVIEW_H diff --git a/src/Gui/DAGView/DAGViewerDesign.svg b/src/Gui/DAGView/DAGViewerDesign.svg new file mode 100644 index 000000000..e8772fb5d --- /dev/null +++ b/src/Gui/DAGView/DAGViewerDesign.svg @@ -0,0 +1,3981 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + Fuse (multi tool) + Sketch + + + Pad + + + Sketch + + + Pocket + + + Fillet + + Typical Linear Branch. i.e. PartDesign + + + + Cube + Fillet Cylinder + Chamfer + Fuse (multi tool) Path Join + + + + + + + + + Fillet + + Cone Target + + + + Tool Tool Cube Fillet + + Chamfer Path Split + + + + + + + + + + Linked Copy Offset Face Datum Plane Sketch Pad + + + + + + + Cube Fillet Chamfer Combo Linked Copy Offset Face Datum Plane Sketch Pad + + + + Target + + Tool + Tool Cube + Fillet + Cylinder + Chamfer + Fuse + View Anatomy + + + + + Fillet + + Cone Label. more columns? like unique name? + + + Connector: width as a factor of font metric Font metric height + Point Size: size controlled by font metric height + Vertical Spacing + Vertical Spacing + Point Spacing. factor of font metric + NodeToIcon Spacing.Factor of font metric. + Maybe alternate Row colors + boost::multi_index GraphLinkRecord App::DocumentObject*, Gui::ViewProviderDocumentObject*,ViewEntryRectItem *,std::string uniqueName,Graph::Vertex Do we need both Gui::ViewProviderDocumentObject and App::DocumentObject? Model Anatomy boost::graph + + GraphicsItem rectangleGraphicsItem pointGraphicsItem textGraphicsItem iconint rowint columnint colorIndexlastVisibleStatepixmapEnabledpixmapDisabledint creationIndex? + + + + + + + + + + + + Edge contains QGraphicItem for connector.BranchTag: Create, Continue, Terminate.Links to same feature will have to be resolved into one connector object + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Icon. Scale to font metric + leaf + Problem:We are going to have the same problem as graphviz in that a small change to the graph could result in quite a bit different topological sort. What to do? We enumerate all vertexes with a creation order index. Then custom DFS(topo sort) that scans children and always traverses child with lowest creation order first? + + + + + Start on left and work right. + + + + + + + + + + + + + + + + + + + + + + + + random thoughts:ignore feature groups?ignore new body objects and it's features?filters?After construction can we keep the view in sync from just the signals?Feature will have a virtual method that returns description of results. Modify = for features like fillet, chamfer, fuse, cut, common. Create = for features like box, cylinder, linked copy, section. Construction = datums. These will determin whether dag forks or stays linear by default. Maybe another virtual method to return target for feature that modify. Relation to claimChildren? Relation to BranchTags: Create, Terminate, Continue? splits go right then up. joins go up then left or right. Debate:all QGraphicsView?QGraphicsView with a qtabelviewall qtableview with node and line generation root + + BranchTag::Create + BranchTag::Continue + BranchTag::Terminate + Cube + Fillet Cylinder + Chamfer + + + + + Fuse + + + Children have multiple parents need new column + Feature priority to force chamfer to inline and make fuse jump to new column? + + Here we are going sideways instead of up. + find each child in topo sorted list.from each child walk the topo list caching occupied columns.Is any childs column open? Cube + Fillet Cylinder + Chamfer + + + + + Fuse + + + + Fuse + + + left and right are always open.everything revolves around the columns + Cone 0 0 0 10 0 1 01 0 0 00 1 0 00 1 0 01 0 0 01 0 0 0 Bitmask per row representing occupied column? + + + + + + + + iconToIcon Spacing.Factor of iconSize. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + iconToText Spacing.Factor of iconSize. + + diff --git a/src/Gui/DlgCheckableMessageBox.cpp b/src/Gui/DlgCheckableMessageBox.cpp new file mode 100644 index 000000000..5dbba1f9d --- /dev/null +++ b/src/Gui/DlgCheckableMessageBox.cpp @@ -0,0 +1,239 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +#endif + +#include "DlgCheckableMessageBox.h" +#include "ui_DlgCheckableMessageBox.h" + +#include +#include + +#include "MainWindow.h" + +#include +//#include + + +namespace Gui { +namespace Dialog { +QByteArray toParamEntry(QString name) +{ + QString tmp = QString::fromLatin1(name.toLatin1()); + name.replace(QString::fromLatin1(" "),QString::fromLatin1("_")); + return name.toLatin1(); +} + +void DlgCheckableMessageBox::showMessage(QString header, QString message, bool check,QString checkText ) +{ + bool checked = App::GetApplication().GetParameterGroupByPath( QByteArray("User parameter:BaseApp/CheckMessages"))->GetBool(toParamEntry(header)); + + if(!checked){ + DlgCheckableMessageBox *mb = new DlgCheckableMessageBox(Gui::getMainWindow()); + mb->setWindowTitle(header); + mb->setIconPixmap(QMessageBox::standardIcon(QMessageBox::Warning)); + mb->setText(message); + mb->setPrefEntry(header); + mb->setCheckBoxText(checkText); + mb->setChecked(check); + mb->setStandardButtons(QDialogButtonBox::Ok); + mb->setDefaultButton(QDialogButtonBox::Ok); + mb->show(); + } +} + + +struct DlgCheckableMessageBoxPrivate { + DlgCheckableMessageBoxPrivate() : clickedButton(0) {} + + Ui::DlgCheckableMessageBox ui; + QAbstractButton *clickedButton; +}; + +DlgCheckableMessageBox::DlgCheckableMessageBox(QWidget *parent) : + QDialog(parent), + m_d(new DlgCheckableMessageBoxPrivate) +{ + setModal(true); + setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); + m_d->ui.setupUi(this); + m_d->ui.pixmapLabel->setVisible(false); + connect(m_d->ui.buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(m_d->ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + connect(m_d->ui.buttonBox, SIGNAL(clicked(QAbstractButton*)), this, SLOT(slotClicked(QAbstractButton*))); +} + +DlgCheckableMessageBox::~DlgCheckableMessageBox() +{ + delete m_d; +} + +void DlgCheckableMessageBox::setPrefEntry( const QString& entry ) +{ + paramEntry = toParamEntry(entry); + bool checked = App::GetApplication().GetParameterGroupByPath( QByteArray("User parameter:BaseApp/CheckMessages"))->GetBool(paramEntry); + setChecked(checked); +} + + +void DlgCheckableMessageBox::slotClicked(QAbstractButton *b) +{ + m_d->clickedButton = b; +} + +QAbstractButton *DlgCheckableMessageBox::clickedButton() const +{ + return m_d->clickedButton; +} + +QDialogButtonBox::StandardButton DlgCheckableMessageBox::clickedStandardButton() const +{ + if (m_d->clickedButton) + return m_d->ui.buttonBox->standardButton(m_d->clickedButton); + return QDialogButtonBox::NoButton; +} + +QString DlgCheckableMessageBox::text() const +{ + return m_d->ui.messageLabel->text(); +} + +void DlgCheckableMessageBox::setText(const QString &t) +{ + m_d->ui.messageLabel->setText(t); +} + +QPixmap DlgCheckableMessageBox::iconPixmap() const +{ + if (const QPixmap *p = m_d->ui.pixmapLabel->pixmap()) + return QPixmap(*p); + return QPixmap(); +} + +void DlgCheckableMessageBox::setIconPixmap(const QPixmap &p) +{ + m_d->ui.pixmapLabel->setPixmap(p); + m_d->ui.pixmapLabel->setVisible(!p.isNull()); +} + +bool DlgCheckableMessageBox::isChecked() const +{ + return m_d->ui.checkBox->isChecked(); +} + +void DlgCheckableMessageBox::setChecked(bool s) +{ + m_d->ui.checkBox->setChecked(s); +} + +QString DlgCheckableMessageBox::checkBoxText() const +{ + return m_d->ui.checkBox->text(); +} + +void DlgCheckableMessageBox::setCheckBoxText(const QString &t) +{ + m_d->ui.checkBox->setText(t); +} + +QDialogButtonBox::StandardButtons DlgCheckableMessageBox::standardButtons() const +{ + return m_d->ui.buttonBox->standardButtons(); +} + +void DlgCheckableMessageBox::setStandardButtons(QDialogButtonBox::StandardButtons s) +{ + m_d->ui.buttonBox->setStandardButtons(s); +} + +QDialogButtonBox::StandardButton DlgCheckableMessageBox::defaultButton() const +{ + Q_FOREACH (QAbstractButton *b, m_d->ui.buttonBox->buttons()) + if (QPushButton *pb = qobject_cast(b)) + if (pb->isDefault()) + return m_d->ui.buttonBox->standardButton(pb); + return QDialogButtonBox::NoButton; +} + +void DlgCheckableMessageBox::setDefaultButton(QDialogButtonBox::StandardButton s) +{ + if (QPushButton *b = m_d->ui.buttonBox->button(s)) { + b->setDefault(true); + b->setFocus(); + } +} + +void DlgCheckableMessageBox::accept() +{ + if(!paramEntry.isEmpty()) + App::GetApplication().GetParameterGroupByPath( QByteArray("User parameter:BaseApp/CheckMessages"))->SetBool(paramEntry,isChecked()); + QDialog::accept(); +} + +void DlgCheckableMessageBox::reject() +{ + if(!paramEntry.isEmpty()) + App::GetApplication().GetParameterGroupByPath( QByteArray("User parameter:BaseApp/CheckMessages"))->SetBool(paramEntry,isChecked()); + QDialog::reject(); +} + +QDialogButtonBox::StandardButton + DlgCheckableMessageBox::question(QWidget *parent, + const QString &title, + const QString &question, + const QString &checkBoxText, + bool *checkBoxSetting, + QDialogButtonBox::StandardButtons buttons, + QDialogButtonBox::StandardButton defaultButton) +{ + DlgCheckableMessageBox mb(parent); + mb.setWindowTitle(title); + mb.setIconPixmap(QMessageBox::standardIcon(QMessageBox::Question)); + mb.setText(question); + mb.setCheckBoxText(checkBoxText); + mb.setChecked(*checkBoxSetting); + mb.setStandardButtons(buttons); + mb.setDefaultButton(defaultButton); + mb.exec(); + *checkBoxSetting = mb.isChecked(); + return mb.clickedStandardButton(); +} + +QMessageBox::StandardButton DlgCheckableMessageBox::dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton db) +{ + return static_cast(int(db)); +} + +} // namespace Dialog +} // namespace Gui + +#include "moc_DlgCheckableMessageBox.cpp" \ No newline at end of file diff --git a/src/Gui/DlgCheckableMessageBox.h b/src/Gui/DlgCheckableMessageBox.h new file mode 100644 index 000000000..9c42a2a28 --- /dev/null +++ b/src/Gui/DlgCheckableMessageBox.h @@ -0,0 +1,116 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef CHECKABLEMESSAGEBOX_H +#define CHECKABLEMESSAGEBOX_H + +//#include "utils_global.h" + +#include +#include +#include + +namespace Gui { +namespace Dialog { + +struct DlgCheckableMessageBoxPrivate; + +/* A messagebox suitable for questions with a + * "Do not ask me again" checkbox. Emulates the QMessageBox API with + * static conveniences. */ + +class GuiExport DlgCheckableMessageBox : public QDialog +{ + Q_OBJECT + Q_PROPERTY(QString text READ text WRITE setText) + Q_PROPERTY(QPixmap iconPixmap READ iconPixmap WRITE setIconPixmap) + Q_PROPERTY(bool isChecked READ isChecked WRITE setChecked) + Q_PROPERTY(QString prefEntry WRITE setPrefEntry) + Q_PROPERTY(QString checkBoxText READ checkBoxText WRITE setCheckBoxText) + Q_PROPERTY(QDialogButtonBox::StandardButtons buttons READ standardButtons WRITE setStandardButtons) + Q_PROPERTY(QDialogButtonBox::StandardButton defaultButton READ defaultButton WRITE setDefaultButton) +public: + explicit DlgCheckableMessageBox(QWidget *parent); + virtual ~DlgCheckableMessageBox(); + + static QDialogButtonBox::StandardButton + question(QWidget *parent, + const QString &title, + const QString &question, + const QString &checkBoxText, + bool *checkBoxSetting, + QDialogButtonBox::StandardButtons buttons = QDialogButtonBox::Yes|QDialogButtonBox::No, + QDialogButtonBox::StandardButton defaultButton = QDialogButtonBox::No); + + QString text() const; + void setText(const QString &); + + void setPrefEntry( const QString& entry ); + + virtual void accept(); + virtual void reject(); + + bool isChecked() const; + void setChecked(bool s); + + QString checkBoxText() const; + void setCheckBoxText(const QString &); + + QDialogButtonBox::StandardButtons standardButtons() const; + void setStandardButtons(QDialogButtonBox::StandardButtons s); + + QDialogButtonBox::StandardButton defaultButton() const; + void setDefaultButton(QDialogButtonBox::StandardButton s); + + // see static QMessageBox::standardPixmap() + QPixmap iconPixmap() const; + void setIconPixmap (const QPixmap &p); + + // Query the result + QAbstractButton *clickedButton() const; + QDialogButtonBox::StandardButton clickedStandardButton() const; + + // Conversion convenience + static QMessageBox::StandardButton dialogButtonBoxToMessageBoxButton(QDialogButtonBox::StandardButton); + + // conviniant show method + static void showMessage(QString haeder, QString message, bool check=false,QString checkText = QString::fromLatin1("Don't show me again")); + +private Q_SLOTS: + void slotClicked(QAbstractButton *b); + +private: + DlgCheckableMessageBoxPrivate *m_d; + QByteArray paramEntry; +}; + +} // namespace Dialog +} // namespace Gui + +#endif // CHECKABLEMESSAGEBOX_H diff --git a/src/Gui/DlgCheckableMessageBox.ui b/src/Gui/DlgCheckableMessageBox.ui new file mode 100644 index 000000000..c918eeeca --- /dev/null +++ b/src/Gui/DlgCheckableMessageBox.ui @@ -0,0 +1,154 @@ + + + Gui::Dialog::DlgCheckableMessageBox + + + + 0 + 0 + 195 + 107 + + + + Dialog + + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 0 + 5 + + + + + + + + + + TextLabel + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + CheckBox + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Minimum + + + + 0 + 5 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + true + + + + + + + + + buttonBox + accepted() + Utils::CheckableMessageBox + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + Utils::CheckableMessageBox + reject() + + + 316 + 260 + + + 286 + 274 + + + + + \ No newline at end of file diff --git a/src/Gui/Document.cpp b/src/Gui/Document.cpp index b0391a1ef..af6413c60 100644 --- a/src/Gui/Document.cpp +++ b/src/Gui/Document.cpp @@ -423,6 +423,7 @@ void Document::slotNewObject(const App::DocumentObject& Obj) Base::Console().Error("App::Document::_RecomputeFeature(): Unknown exception in Feature \"%s\" thrown\n",Obj.getNameInDocument()); } #endif + std::list::iterator vIt; // cycling to all views of the document for (vIt = d->baseViews.begin();vIt != d->baseViews.end();++vIt) { @@ -430,9 +431,12 @@ void Document::slotNewObject(const App::DocumentObject& Obj) if (activeView) activeView->getViewer()->addViewProvider(pcProvider); } - + // adding to the tree signalNewObject(*pcProvider); + + // it is possible that a new viewprovider aready claims children + handleChildren3D(pcProvider); } else { Base::Console().Warning("Gui::Document::slotNewObject() no view provider for the object %s found\n",cName.c_str()); @@ -472,7 +476,7 @@ void Document::slotDeletedObject(const App::DocumentObject& Obj) void Document::slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop) { - //Base::Console().Log("Document::slotChangedObject() called\n"); + //Base::Console().Log("Document::slotChangedObject() called\n"); ViewProvider* viewProvider = getViewProvider(&Obj); if (viewProvider) { try { @@ -491,35 +495,7 @@ void Document::slotChangedObject(const App::DocumentObject& Obj, const App::Prop Base::Console().Error("Cannot update representation for '%s'.\n", Obj.getNameInDocument()); } - // check for children - if (viewProvider->getChildRoot()) { - std::vector children = viewProvider->claimChildren3D(); - SoGroup* childGroup = viewProvider->getChildRoot(); - - // size not the same -> build up the list new - if(childGroup->getNumChildren() != static_cast(children.size())){ - - childGroup->removeAllChildren(); - - for(std::vector::iterator it=children.begin();it!=children.end();++it){ - ViewProvider* ChildViewProvider = getViewProvider(*it); - if(ChildViewProvider) { - SoSeparator* childRootNode = ChildViewProvider->getRoot(); - childGroup->addChild(childRootNode); - - // cycling to all views of the document to remove the viewprovider from the viewer itself - for (std::list::iterator vIt = d->baseViews.begin();vIt != d->baseViews.end();++vIt) { - View3DInventor *activeView = dynamic_cast(*vIt); - if (activeView && viewProvider) { - if (d->_editViewProvider == ChildViewProvider) - resetEdit(); - activeView->getViewer()->removeViewProvider(ChildViewProvider); - } - } - } - } - } - } + handleChildren3D(viewProvider); if (viewProvider->isDerivedFrom(ViewProviderDocumentObject::getClassTypeId())) signalChangedObject(static_cast(*viewProvider), Prop); @@ -1030,13 +1006,25 @@ void Document::createView(const Base::Type& typeId) view3D->getViewer()->setOverrideMode(overrideMode); } - // attach the viewprovider + // attach the viewproviders. we need to make sure that we only attach the toplevel ones + // and not viewproviders which are claimed by other providers. To ensure this we first + // add all providers and then remove the ones already claimed std::map::const_iterator It1; - for (It1=d->_ViewProviderMap.begin();It1!=d->_ViewProviderMap.end();++It1) + std::vector child_vps; + for (It1=d->_ViewProviderMap.begin();It1!=d->_ViewProviderMap.end();++It1) { view3D->getViewer()->addViewProvider(It1->second); + std::vector children = It1->second->claimChildren3D(); + child_vps.insert(child_vps.end(), children.begin(), children.end()); + } std::map::const_iterator It2; - for (It2=d->_ViewProviderMapAnnotation.begin();It2!=d->_ViewProviderMapAnnotation.end();++It2) + for (It2=d->_ViewProviderMapAnnotation.begin();It2!=d->_ViewProviderMapAnnotation.end();++It2) { view3D->getViewer()->addViewProvider(It2->second); + std::vector children = It2->second->claimChildren3D(); + child_vps.insert(child_vps.end(), children.begin(), children.end()); + } + + for(App::DocumentObject* obj : child_vps) + view3D->getViewer()->removeViewProvider(getViewProvider(obj)); const char* name = getDocument()->Label.getValue(); QString title = QString::fromLatin1("%1 : %2[*]") @@ -1375,3 +1363,40 @@ PyObject* Document::getPyObject(void) _pcDocPy->IncRef(); return _pcDocPy; } + +void Document::handleChildren3D(ViewProvider* viewProvider) +{ + // check for children + if (viewProvider->getChildRoot()) { + std::vector children = viewProvider->claimChildren3D(); + SoGroup* childGroup = viewProvider->getChildRoot(); + + // size not the same -> build up the list new + if(childGroup->getNumChildren() != static_cast(children.size())){ + + childGroup->removeAllChildren(); + + for(std::vector::iterator it=children.begin();it!=children.end();++it){ + ViewProvider* ChildViewProvider = getViewProvider(*it); + if(ChildViewProvider) { + SoSeparator* childRootNode = ChildViewProvider->getRoot(); + childGroup->addChild(childRootNode); + + // cycling to all views of the document to remove the viewprovider from the viewer itself + for (std::list::iterator vIt = d->baseViews.begin();vIt != d->baseViews.end();++vIt) { + View3DInventor *activeView = dynamic_cast(*vIt); + if (activeView && viewProvider && activeView->getViewer()->hasViewProvider(ChildViewProvider)) { + // Note about hasViewProvider() + //remove the viewprovider serves the purpose of detaching the inventor nodes from the + //top level root in the viewer. However, if some of the children were grouped beneath the object + //earlier they are not anymore part of the toplevel inventor node. we need to check for that. + if (d->_editViewProvider == ChildViewProvider) + resetEdit(); + activeView->getViewer()->removeViewProvider(ChildViewProvider); + } + } + } + } + } + } +} diff --git a/src/Gui/Document.h b/src/Gui/Document.h index b79cba96b..db0fd6ae9 100644 --- a/src/Gui/Document.h +++ b/src/Gui/Document.h @@ -51,12 +51,13 @@ class ViewProvider; class ViewProviderDocumentObject; class Application; class DocumentPy; +enum HighlightMode; /** The Gui Document * This is the document on GUI level. Its main responsibility is keeping * track off open windows for a document and warning on unsaved closes. * All handled views on the document must inherit from MDIView - * @see App::Document + * @see App::Document * @see MDIView * @author Jürgen Riegel */ @@ -141,7 +142,7 @@ public: void setModified(bool); bool isModified() const; - /// Getter for the App Document + /// Getter for the App Document App::Document* getDocument(void) const; /** @name methods for View handling */ @@ -152,7 +153,7 @@ public: Gui::MDIView* getViewOfViewProvider(Gui::ViewProvider*) const; /// Create a new view void createView(const Base::Type& typeId); - /** send messages to the active view + /** send messages to the active view * Send a specific massage to the active view and is able to recive a * return massage */ @@ -167,7 +168,7 @@ public: /// Attach a view (get called by the MDIView constructor) void attachView(Gui::BaseView* pcView, bool bPassiv=false); /// Detach a view (get called by the MDIView destructor) - void detachView(Gui::BaseView* pcView, bool bPassiv=false); + void detachView(Gui::BaseView* pcView, bool bPassiv=false); /// helper for selection ViewProvider* getViewProviderByPathFromTail(SoPath * path) const; /// call update on all attached views @@ -239,6 +240,9 @@ protected: Gui::DocumentPy *_pcDocPy; private: + //handles the scene graph nodes to correctly group child and parents + void handleChildren3D(ViewProvider* viewProvider); + struct DocumentP* d; static int _iDocCount; diff --git a/src/Gui/Icons/CoordinateSystem.svg b/src/Gui/Icons/CoordinateSystem.svg new file mode 100644 index 000000000..8f7dc0d2d --- /dev/null +++ b/src/Gui/Icons/CoordinateSystem.svg @@ -0,0 +1,128 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/src/Gui/Icons/dagViewFail.svg b/src/Gui/Icons/dagViewFail.svg new file mode 100644 index 000000000..f1592238f --- /dev/null +++ b/src/Gui/Icons/dagViewFail.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/src/Gui/Icons/dagViewPass.svg b/src/Gui/Icons/dagViewPass.svg new file mode 100644 index 000000000..728346f51 --- /dev/null +++ b/src/Gui/Icons/dagViewPass.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/src/Gui/Icons/dagViewPending.svg b/src/Gui/Icons/dagViewPending.svg new file mode 100644 index 000000000..13608ddc6 --- /dev/null +++ b/src/Gui/Icons/dagViewPending.svg @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Gui/Icons/dagViewVisible.svg b/src/Gui/Icons/dagViewVisible.svg new file mode 100644 index 000000000..3afe12633 --- /dev/null +++ b/src/Gui/Icons/dagViewVisible.svg @@ -0,0 +1,196 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/src/Gui/Icons/resource.qrc b/src/Gui/Icons/resource.qrc index 2890c9f65..c978f07ec 100644 --- a/src/Gui/Icons/resource.qrc +++ b/src/Gui/Icons/resource.qrc @@ -102,6 +102,10 @@ Tree_Annotation.svg Tree_Dimension.svg Tree_Python.svg + dagViewVisible.svg + dagViewPass.svg + dagViewFail.svg + dagViewPending.svg Part_Measure_Clear_All.svg Part_Measure_Toggle_All.svg spaceball_button.svg @@ -117,6 +121,7 @@ DrawStyleShaded.svg DrawStyleWireFrame.svg user.svg + CoordinateSystem.svg diff --git a/src/Gui/Inventor/SoAutoZoomTranslation.cpp b/src/Gui/Inventor/SoAutoZoomTranslation.cpp index 5137d7f74..b4cfcc68b 100644 --- a/src/Gui/Inventor/SoAutoZoomTranslation.cpp +++ b/src/Gui/Inventor/SoAutoZoomTranslation.cpp @@ -25,7 +25,7 @@ #ifndef _PreComp_ # include # include -# include +# include # include #endif @@ -138,7 +138,7 @@ void SoAutoZoomTranslation::getMatrix(SoGetMatrixAction * action) void SoAutoZoomTranslation::callback(SoCallbackAction * action) { - // Base::Console().Log("callback\n"); + // Base::Console().Log("callback\n"); SoAutoZoomTranslation::doAction((SoAction*)action); } diff --git a/src/Gui/MDIView.cpp b/src/Gui/MDIView.cpp index 56c5dae1f..5ea1ecafe 100644 --- a/src/Gui/MDIView.cpp +++ b/src/Gui/MDIView.cpp @@ -24,6 +24,8 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include +# include # include # include # include @@ -38,6 +40,7 @@ #include "Document.h" #include "Application.h" #include "MainWindow.h" +#include "ViewProviderDocumentObject.h" using namespace Gui; @@ -48,6 +51,13 @@ MDIView::MDIView(Gui::Document* pcDocument,QWidget* parent, Qt::WindowFlags wfla : QMainWindow(parent, wflags), BaseView(pcDocument),currentMode(Child), wstate(Qt::WindowNoState) { setAttribute(Qt::WA_DeleteOnClose); + + if (pcDocument) + { + connectDelObject = pcDocument->signalDeletedObject.connect + (boost::bind(&ActiveObjectList::objectDeleted, &ActiveObjects, _1)); + assert(connectDelObject.connected()); + } } MDIView::~MDIView() @@ -70,6 +80,8 @@ MDIView::~MDIView() } } } + if (connectDelObject.connected()) + connectDelObject.disconnect(); } void MDIView::deleteSelf() diff --git a/src/Gui/MDIView.h b/src/Gui/MDIView.h index 5892169c1..8faac4dfe 100644 --- a/src/Gui/MDIView.h +++ b/src/Gui/MDIView.h @@ -26,6 +26,7 @@ #include "View.h" #include +#include "ActiveObjectList.h" QT_BEGIN_NAMESPACE class QPrinter; @@ -34,6 +35,7 @@ QT_END_NAMESPACE namespace Gui { class Document; +class ViewProviderDocumentObject; /** Base class of all windows belonging to a document. * There are two ways of belonging to a document: @@ -108,6 +110,22 @@ public: virtual void setCurrentViewMode(ViewMode mode); ViewMode currentViewMode() const { return currentMode; } + + /// access getter for the active object list + template + inline _T getActiveObject(const char* name) const + { + return ActiveObjects.getObject<_T>(name); + }; + void setActiveObject(App::DocumentObject*o, const char*n) + { + ActiveObjects.setObject(o, n); + }; + bool hasActiveObject(const char*n) const + { + return ActiveObjects.hasObject(n); + }; + public Q_SLOTS: virtual void setOverrideCursor(const QCursor&); virtual void restoreOverrideCursor(); @@ -130,6 +148,10 @@ protected: private: ViewMode currentMode; Qt::WindowStates wstate; + // list of active objects of this view + ActiveObjectList ActiveObjects; + typedef boost::BOOST_SIGNALS_NAMESPACE::connection Connection; + Connection connectDelObject; //remove active object upon delete. }; } // namespace Gui diff --git a/src/Gui/MainWindow.cpp b/src/Gui/MainWindow.cpp index 625d07865..42cd045a9 100644 --- a/src/Gui/MainWindow.cpp +++ b/src/Gui/MainWindow.cpp @@ -98,6 +98,7 @@ #include "CombiView.h" #include "PythonConsole.h" #include "TaskView/TaskView.h" +#include "DAGView/DAGView.h" #include "DlgTipOfTheDayImp.h" #include "DlgUndoRedo.h" @@ -374,6 +375,20 @@ MainWindow::MainWindow(QWidget * parent, Qt::WindowFlags f) pcPython->setObjectName (QString::fromLatin1(QT_TRANSLATE_NOOP("QDockWidget","Python console"))); pDockMgr->registerDockWindow("Std_PythonView", pcPython); + + //Dag View. + //work through parameter. + ParameterGrp::handle group = App::GetApplication().GetUserParameter(). + GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DAGView"); + bool enabled = group->GetBool("Enabled", false); + group->SetBool("Enabled", enabled); //ensure entry exists. + if (enabled) + { + DAG::DockWindow *dagDockWindow = new DAG::DockWindow(nullptr, this); + dagDockWindow->setObjectName + (QString::fromAscii(QT_TRANSLATE_NOOP("QDockWidget","DAG View"))); + pDockMgr->registerDockWindow("Std_DAGView", dagDockWindow); + } #if 0 //defined(Q_OS_WIN32) this portion of code is not able to run with a vanilla Qtlib build on Windows. // The MainWindowTabBar is used to show tabbed dock windows with icons diff --git a/src/Gui/ProjectView.cpp b/src/Gui/ProjectView.cpp index 66b6a30ce..327ac4bc6 100644 --- a/src/Gui/ProjectView.cpp +++ b/src/Gui/ProjectView.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) 2012 Jürgen Riegel * + * Copyright (c) 2012 Juergen Riegel * * * * This file is part of the FreeCAD CAx development system. * * * diff --git a/src/Gui/ProjectView.h b/src/Gui/ProjectView.h index 7b4538618..c6085fc94 100644 --- a/src/Gui/ProjectView.h +++ b/src/Gui/ProjectView.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) 2012 Jürgen Riegel * + * Copyright (c) 2012 Juergen Riegel * * * * This file is part of the FreeCAD CAx development system. * * * diff --git a/src/Gui/Qt4All.h b/src/Gui/Qt4All.h index 195b0b6de..5e7d38f91 100644 --- a/src/Gui/Qt4All.h +++ b/src/Gui/Qt4All.h @@ -51,6 +51,7 @@ #include #include // QtGui +#include #include #include #include @@ -76,8 +77,10 @@ #include #include #include +#include #include #include +#include #include #include #include diff --git a/src/Gui/Selection.cpp b/src/Gui/Selection.cpp index bcbfbead1..2aeb87ffa 100644 --- a/src/Gui/Selection.cpp +++ b/src/Gui/Selection.cpp @@ -394,6 +394,30 @@ std::vector SelectionSingleton::getSelectionEx(const char* pDoc return temp; } +int SelectionSingleton::getAsPropertyLinkSubList(App::PropertyLinkSubList &prop) const +{ + std::vector sel = this->getSelectionEx(); + std::vector objs; objs.reserve(sel.size()*2); + std::vector subs; subs.reserve(sel.size()*2); + for( int iobj = 0 ; iobj < sel.size() ; iobj++ ){ + Gui::SelectionObject &selitem = sel[iobj]; + App::DocumentObject* obj = selitem.getObject(); + const std::vector &subnames = selitem.getSubNames(); + if (subnames.size() == 0){//whole object is selected + objs.push_back(obj); + subs.push_back(std::string()); + } else { + for( int isub = 0 ; isub < subnames.size() ; isub++ ){ + objs.push_back(obj); + subs.push_back(subnames[isub]); + } + } + } + assert(objs.size()==subs.size()); + prop.setValues(objs, subs); + return objs.size(); +} + vector SelectionSingleton::getObjectsOfType(const Base::Type& typeId, const char* pDocName) const { std::vector temp; @@ -461,13 +485,21 @@ bool SelectionSingleton::setPreselect(const char* pDocName, const char* pObjectN if (pObjectName) { App::DocumentObject* pObject = pDoc->getObject(pObjectName); if (!ActiveGate->allow(pDoc,pObject,pSubName)) { - snprintf(buf,512,"Not allowed: %s.%s.%s ",pDocName - ,pObjectName - ,pSubName - ); + QString msg; + if (ActiveGate->notAllowedReason.length() > 0){ + msg = QObject::tr(ActiveGate->notAllowedReason.c_str()); + } else { + msg = QCoreApplication::translate("SelectionFilter","Not allowed:"); + } + msg.append( + QObject::tr(" %1.%2.%3 ") + .arg(QString::fromAscii(pDocName)) + .arg(QString::fromAscii(pObjectName)) + .arg(QString::fromAscii(pSubName)) + ); if (getMainWindow()) { - getMainWindow()->showMessage(QString::fromLatin1(buf),3000); + getMainWindow()->showMessage(msg,3000); Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView(); mdi->setOverrideCursor(QCursor(Qt::ForbiddenCursor)); } @@ -641,10 +673,17 @@ bool SelectionSingleton::addSelection(const char* pDocName, const char* pObjectN if (ActiveGate) { if (!ActiveGate->allow(temp.pDoc,temp.pObject,pSubName)) { if (getMainWindow()) { - getMainWindow()->showMessage(QString::fromLatin1("Selection not allowed by filter"),5000); + QString msg; + if (ActiveGate->notAllowedReason.length() > 0) { + msg = QObject::tr(ActiveGate->notAllowedReason.c_str()); + } else { + msg = QCoreApplication::translate("SelectionFilter","Selection not allowed by filter"); + } + getMainWindow()->showMessage(msg,5000); Gui::MDIView* mdi = Gui::Application::Instance->activeDocument()->getActiveView(); mdi->setOverrideCursor(Qt::ForbiddenCursor); } + ActiveGate->notAllowedReason.clear(); QApplication::beep(); return false; } diff --git a/src/Gui/Selection.h b/src/Gui/Selection.h index 6e411d319..1ec24569c 100644 --- a/src/Gui/Selection.h +++ b/src/Gui/Selection.h @@ -178,6 +178,14 @@ class GuiExport SelectionGate public: virtual ~SelectionGate(){} virtual bool allow(App::Document*,App::DocumentObject*, const char*)=0; + + /** + * @brief notAllowedReason is a string that sets the message to be + * displayed in statusbar for cluing the user on why is the selection not + * allowed. Set this variable in allow() implementation. Enclose the + * literal into QT_TR_NOOP() for translatability. + */ + std::string notAllowedReason; }; @@ -287,6 +295,13 @@ public: */ std::vector getSelectionEx(const char* pDocName=0,Base::Type typeId=App::DocumentObject::getClassTypeId()) const; + /** + * @brief getAsPropertyLinkSubList fills PropertyLinkSubList with current selection. + * @param prop (output). The property object to recieve links + * @return the number of items written to the link + */ + int getAsPropertyLinkSubList(App::PropertyLinkSubList &prop) const; + /** Returns a vector of all selection objects of all documents. */ std::vector getCompleteSelection() const; bool hasSelection() const; diff --git a/src/Gui/SoFCSelection.cpp b/src/Gui/SoFCSelection.cpp index 27e939790..53b1e1b7b 100644 --- a/src/Gui/SoFCSelection.cpp +++ b/src/Gui/SoFCSelection.cpp @@ -802,10 +802,10 @@ SoFCSelection::redrawHighlighted(SoAction * action , SbBool doHighlight ) //void* window; //void* context; //void *display; - QGLWidget* window; + QGLWidget* window; SoGLRenderAction *glAction; //SoWindowElement::get(state, window, context, display, glAction); - SoGLWidgetElement::get(state, window); + SoGLWidgetElement::get(state, window); SoGLRenderActionElement::get(state, glAction); // If we don't have a current window, then simply return... @@ -917,4 +917,36 @@ SoFCSelection::isHighlighted(SoAction *action) *currenthighlight == *actionPath); } +void SoFCSelection::applySettings () +{ + // TODO Some view providers got copy of this code: make them use this (2015-09-03, Fat-Zer) + // Note: SoFCUnifiedSelection got the same code, keep in sync or think about a way to share it + float transparency; + ParameterGrp::handle hGrp = Gui::WindowParameter::getDefaultParameter()->GetGroup("View"); + bool enablePre = hGrp->GetBool("EnablePreselection", true); + bool enableSel = hGrp->GetBool("EnableSelection", true); + if (!enablePre) { + this->highlightMode = Gui::SoFCSelection::OFF; + } + else { + // Search for a user defined value with the current color as default + SbColor highlightColor = this->colorHighlight.getValue(); + unsigned long highlight = (unsigned long)(highlightColor.getPackedValue()); + highlight = hGrp->GetUnsigned("HighlightColor", highlight); + highlightColor.setPackedValue((uint32_t)highlight, transparency); + this->colorHighlight.setValue(highlightColor); + } + if (!enableSel) { + this->selectionMode = Gui::SoFCSelection::SEL_OFF; + } + else { + // Do the same with the selection color + SbColor selectionColor = this->colorSelection.getValue(); + unsigned long selection = (unsigned long)(selectionColor.getPackedValue()); + selection = hGrp->GetUnsigned("SelectionColor", selection); + selectionColor.setPackedValue((uint32_t)selection, transparency); + this->colorSelection.setValue(selectionColor); + } +} + //#undef THIS diff --git a/src/Gui/SoFCSelection.h b/src/Gui/SoFCSelection.h index 656f3ccdf..e1ae8a98a 100644 --- a/src/Gui/SoFCSelection.h +++ b/src/Gui/SoFCSelection.h @@ -23,15 +23,15 @@ #ifndef GUI_SOFCSELECTION_H #define GUI_SOFCSELECTION_H -# ifdef FC_OS_MACOSX -# include -# else +# ifdef FC_OS_MACOSX +# include +# else # ifdef FC_OS_WIN32 # define NOMINMAX # include -# endif -# include -# endif +# endif +# include +# endif #include #include @@ -61,6 +61,9 @@ public: static void finish(void); SoFCSelection(void); + /// Load highlight settings from the configuration + void applySettings (); + enum HighlightModes { AUTO, ON, OFF }; diff --git a/src/Gui/SoFCUnifiedSelection.h b/src/Gui/SoFCUnifiedSelection.h index 894ab1c8c..aa3aaa7f9 100644 --- a/src/Gui/SoFCUnifiedSelection.h +++ b/src/Gui/SoFCUnifiedSelection.h @@ -23,15 +23,15 @@ #ifndef GUI_SOFCUNIFIEDSELECTION_H #define GUI_SOFCUNIFIEDSELECTION_H -# ifdef FC_OS_MACOSX -# include -# else +# ifdef FC_OS_MACOSX +# include +# else # ifdef FC_OS_WIN32 # define NOMINMAX # include -# endif -# include -# endif +# endif +# include +# endif #include #include diff --git a/src/Gui/TaskView/TaskDialog.cpp b/src/Gui/TaskView/TaskDialog.cpp index c389d3a3d..5c784c602 100644 --- a/src/Gui/TaskView/TaskDialog.cpp +++ b/src/Gui/TaskView/TaskDialog.cpp @@ -100,4 +100,6 @@ void TaskDialog::helpRequested() } + + #include "moc_TaskDialog.cpp" diff --git a/src/Gui/TaskView/TaskDialog.h b/src/Gui/TaskView/TaskDialog.h index 2f05ec435..39cafc0f6 100644 --- a/src/Gui/TaskView/TaskDialog.h +++ b/src/Gui/TaskView/TaskDialog.h @@ -104,6 +104,13 @@ public: /// is called by the framework if the user press the help button virtual void helpRequested(); + void emitDestructionSignal() { + Q_EMIT aboutToBeDestroyed(); + } + +Q_SIGNALS: + void aboutToBeDestroyed(); + protected: /// List of TaskBoxes of that dialog std::vector Content; diff --git a/src/Gui/TaskView/TaskView.cpp b/src/Gui/TaskView/TaskView.cpp index 38640f2a1..c08addf9c 100644 --- a/src/Gui/TaskView/TaskView.cpp +++ b/src/Gui/TaskView/TaskView.cpp @@ -116,7 +116,7 @@ void TaskGroup::actionEvent (QActionEvent* e) TaskIconLabel *label = new TaskIconLabel( action->icon(), action->text(), this); this->addIconLabel(label); - connect(label,SIGNAL(clicked()),action,SIGNAL(triggered())); + connect(label,SIGNAL(clicked()),action,SIGNAL(triggered()),Qt::QueuedConnection); break; } case QEvent::ActionChanged: @@ -570,12 +570,13 @@ void TaskView::removeDialog(void) ActiveCtrl = 0; } + TaskDialog* remove = NULL; if (ActiveDialog) { const std::vector &cont = ActiveDialog->getDialogContent(); for(std::vector::const_iterator it=cont.begin();it!=cont.end();++it){ taskPanel->removeWidget(*it); } - delete ActiveDialog; + remove = ActiveDialog; ActiveDialog = 0; } @@ -583,6 +584,11 @@ void TaskView::removeDialog(void) // put the watcher back in control addTaskWatcher(); + + if(remove) { + remove->emitDestructionSignal(); + delete remove; + } } void TaskView::updateWatcher(void) diff --git a/src/Gui/TaskView/TaskWatcher.cpp b/src/Gui/TaskView/TaskWatcher.cpp index 4c6f99d63..5e08c71d1 100644 --- a/src/Gui/TaskView/TaskWatcher.cpp +++ b/src/Gui/TaskView/TaskWatcher.cpp @@ -102,9 +102,6 @@ TaskWatcherCommands::TaskWatcherCommands(const char* Filter,const char* commands Content.push_back(tb); } -TaskWatcherCommands::~TaskWatcherCommands() -{ -} //==== implementer =========================================================================== @@ -128,9 +125,7 @@ TaskWatcherCommandsEmptyDoc::TaskWatcherCommandsEmptyDoc(const char* commands[], { } -TaskWatcherCommandsEmptyDoc::~TaskWatcherCommandsEmptyDoc() -{ -} + //==== implementer =========================================================================== @@ -169,4 +164,5 @@ bool TaskWatcherCommandsEmptySelection::shouldShow() return (App::GetApplication().getActiveDocument() && Gui::Selection().size() == 0); } + #include "moc_TaskWatcher.cpp" diff --git a/src/Gui/TaskView/TaskWatcher.h b/src/Gui/TaskView/TaskWatcher.h index 613bec7ec..cd6e26df2 100644 --- a/src/Gui/TaskView/TaskWatcher.h +++ b/src/Gui/TaskView/TaskWatcher.h @@ -48,7 +48,7 @@ class GuiExport TaskWatcher : public QObject, public Gui::SelectionFilter public: TaskWatcher(const char* Filter); - ~TaskWatcher(); + virtual ~TaskWatcher(); std::vector &getWatcherContent(void); @@ -71,7 +71,6 @@ class GuiExport TaskWatcherCommands : public TaskWatcher public: TaskWatcherCommands(const char* Filter,const char* commands[], const char* name, const char* pixmap); - ~TaskWatcherCommands(); public: /// is called wenn the document or the Selection changes. @@ -88,7 +87,6 @@ class GuiExport TaskWatcherCommandsEmptyDoc : public TaskWatcherCommands public: TaskWatcherCommandsEmptyDoc(const char* commands[], const char* name, const char* pixmap); - ~TaskWatcherCommandsEmptyDoc(); public: /// is called wenn the document or the Selection changes. diff --git a/src/Gui/Tree.cpp b/src/Gui/Tree.cpp index dba94c0df..ca4c8ff01 100644 --- a/src/Gui/Tree.cpp +++ b/src/Gui/Tree.cpp @@ -113,7 +113,7 @@ TreeWidget::TreeWidget(QWidget* parent) this->statusTimer = new QTimer(this); - connect(this->statusTimer, SIGNAL(timeout()), + connect(this->statusTimer, SIGNAL(timeout()), this, SLOT(onTestStatus())); connect(this, SIGNAL(itemEntered(QTreeWidgetItem*, int)), this, SLOT(onItemEntered(QTreeWidgetItem*))); @@ -444,7 +444,10 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event) } } else if (targetitem->type() == TreeWidget::ObjectType) { - Gui::ViewProviderDocumentObject* vp = static_cast(targetitem)->object(); + + DocumentObjectItem* targetItemObj = static_cast(targetitem); + Gui::ViewProviderDocumentObject* vp = targetItemObj->object(); + if (!vp->canDropObjects()) { event->ignore(); } @@ -456,6 +459,10 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event) App::DocumentObject* grp = vp->getObject(); App::Document* doc = grp->getDocument(); QList idxs = selectedIndexes(); + + std::vector dropObjects; + dropObjects.reserve(idxs.size()); + for (QList::Iterator it = idxs.begin(); it != idxs.end(); ++it) { QTreeWidgetItem* item = itemFromIndex(*it); if (item->type() != TreeWidget::ObjectType) { @@ -469,6 +476,8 @@ void TreeWidget::dragMoveEvent(QDragMoveEvent *event) return; } + dropObjects.push_back(obj); + // To avoid a cylic dependency it must be made sure to not allow to // drag'n'drop a tree item onto a child or grandchild item of it. if (static_cast(targetitem)->isChildOfItem( @@ -506,7 +515,7 @@ void TreeWidget::dropEvent(QDropEvent *event) // one of the source items is also the destination item, that's not allowed if (this->isItemSelected(targetitem)) return; - + // filter out the selected items we cannot handle QList items; QList idxs = selectedIndexes(); @@ -528,20 +537,26 @@ void TreeWidget::dropEvent(QDropEvent *event) if (targetitem->type() == TreeWidget::ObjectType) { // add object to group - Gui::ViewProviderDocumentObject* vp = static_cast(targetitem)->object(); + DocumentObjectItem* targetItemObj = static_cast(targetitem); + Gui::ViewProviderDocumentObject* vp = targetItemObj->object(); App::DocumentObject* grp = vp->getObject(); if (!vp->canDropObjects()) { return; // no group like object } + std::vector dropObjects; + dropObjects.reserve(idxs.size()); + // Open command App::Document* doc = grp->getDocument(); Gui::Document* gui = Gui::Application::Instance->getDocument(doc); - gui->openCommand("Move object"); + for (QList::Iterator it = items.begin(); it != items.end(); ++it) { Gui::ViewProviderDocumentObject* vpc = static_cast(*it)->object(); App::DocumentObject* obj = vpc->getObject(); + dropObjects.push_back(obj); + // does this have a parent object QTreeWidgetItem* parent = (*it)->parent(); if (parent && parent->type() == TreeWidget::ObjectType) { @@ -552,7 +567,7 @@ void TreeWidget::dropEvent(QDropEvent *event) // now add the object to the target object vp->dropObject(obj); } - gui->commitCommand(); + targetItemObj->drop(dropObjects,event->keyboardModifiers(),event->mouseButtons(),event->pos()); } else if (targetitem->type() == TreeWidget::DocumentType) { // Open command @@ -655,7 +670,7 @@ void TreeWidget::onTestStatus(void) void TreeWidget::onItemEntered(QTreeWidgetItem * item) { // object item selected - if (item && item->type() == TreeWidget::ObjectType) { + if ( item && item->type() == TreeWidget::ObjectType ) { DocumentObjectItem* obj = static_cast(item); obj->displayStatusInfo(); } @@ -802,7 +817,7 @@ void TreeWidget::setItemsSelected (const QList items, bool se QItemSelection range; for (QList::const_iterator it = items.begin(); it != items.end(); ++it) range.select(this->indexFromItem(*it),this->indexFromItem(*it)); - selectionModel()->select(range, select ? + selectionModel()->select(range, select ? QItemSelectionModel::Select : QItemSelectionModel::Deselect); } @@ -819,7 +834,7 @@ TreeDockWidget::TreeDockWidget(Gui::Document* pcDocument,QWidget *parent) ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/TreeView"); this->treeWidget->setIndentation(hGrp->GetInt("Indentation", this->treeWidget->indentation())); - QGridLayout* pLayout = new QGridLayout(this); + QGridLayout* pLayout = new QGridLayout(this); pLayout->setSpacing(0); pLayout->setMargin (0); pLayout->addWidget(this->treeWidget, 0, 0 ); @@ -861,11 +876,13 @@ DocumentItem::~DocumentItem() connectExpObject.disconnect(); } + + void DocumentItem::slotInEdit(const Gui::ViewProviderDocumentObject& v) { std::string name (v.getObject()->getNameInDocument()); std::map::iterator it = ObjectMap.find(name); - if (it != ObjectMap.end()) + if (it != ObjectMap.end()) it->second->setBackgroundColor(0,Qt::yellow); } @@ -874,24 +891,31 @@ void DocumentItem::slotResetEdit(const Gui::ViewProviderDocumentObject& v) std::string name (v.getObject()->getNameInDocument()); std::map::iterator it = ObjectMap.find(name); if (it != ObjectMap.end()) { - it->second->setData(0, Qt::BackgroundColorRole,QVariant()); + it->second->setData(0, Qt::BackgroundColorRole,QVariant()); } } void DocumentItem::slotNewObject(const Gui::ViewProviderDocumentObject& obj) { - std::string displayName = obj.getObject()->Label.getValue(); - std::string objectName = obj.getObject()->getNameInDocument(); - std::map::iterator it = ObjectMap.find(objectName); - if (it == ObjectMap.end()) { - // cast to non-const object - DocumentObjectItem* item = new DocumentObjectItem( - const_cast(&obj), this); - item->setIcon(0, obj.getIcon()); - item->setText(0, QString::fromUtf8(displayName.c_str())); - ObjectMap[objectName] = item; - } else { - Base::Console().Warning("DocumentItem::slotNewObject: Cannot add view provider twice.\n"); + if (obj.showInTree()){ + std::string displayName = obj.getObject()->Label.getValue(); + std::string objectName = obj.getObject()->getNameInDocument(); + std::map::iterator it = ObjectMap.find(objectName); + if (it == ObjectMap.end()) { + // cast to non-const object + DocumentObjectItem* item = new DocumentObjectItem( + const_cast(&obj), this); + item->setIcon(0, obj.getIcon()); + item->setText(0, QString::fromUtf8(displayName.c_str())); + ObjectMap[objectName] = item; + + // it may be possible that the new object claims already existing objects. If this is the + // case we need to make sure this is shown by the tree + if(!obj.claimChildren().empty()) + slotChangeObject(obj); + }else { + Base::Console().Warning("DocumentItem::slotNewObject: Cannot add view provider twice.\n"); + } } } @@ -943,25 +967,53 @@ void DocumentItem::slotChangeObject(const Gui::ViewProviderDocumentObject& view) std::string objectName = obj->getNameInDocument(); std::map::iterator it = ObjectMap.find(objectName); if (it != ObjectMap.end()) { - // use new grouping style - std::set children; - std::vector group = view.claimChildren(); - for (std::vector::iterator jt = group.begin(); jt != group.end(); ++jt) { - if (*jt) { - const char* internalName = (*jt)->getNameInDocument(); - if (internalName) { - std::map::iterator kt = ObjectMap.find(internalName); - if (kt != ObjectMap.end()) { - children.insert(kt->second); - QTreeWidgetItem* parent = kt->second->parent(); - if (parent && parent != it->second) { - if (it->second != kt->second) { - int index = parent->indexOfChild(kt->second); - parent->takeChild(index); - it->second->addChild(kt->second); - } - else { - Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Object references to itself.\n"); + // use new grouping style + DocumentObjectItem* parent_of_group = it->second; + std::set children; + std::vector group = view.claimChildren(); + int group_index = 0; // counter of children inserted to the tree + for (std::vector::iterator jt = group.begin(); jt != group.end(); ++jt) { + if ((*jt) && view.getObject()->getDocument()->isIn(*jt)){ + // Note: It is possible that we receive an invalid pointer from claimChildren(), e.g. if multiple properties + // were changed in a transaction and slotChangedObject() is triggered by one property being reset + // before the invalid pointer has been removed from another. Currently this happens for PartDesign::Body + // when cancelling a new feature in the dialog. First the new feature is deleted, then the Tip property is + // reset, but claimChildren() accesses the Model property which still contains the pointer to the deleted feature + const char* internalName = (*jt)->getNameInDocument(); + if (internalName) { + std::map::iterator kt = ObjectMap.find(internalName); + if (kt != ObjectMap.end()) { + DocumentObjectItem* child_of_group = kt->second; + children.insert(child_of_group); + QTreeWidgetItem* parent_of_child = child_of_group->parent(); + + if (parent_of_child) { + if (parent_of_child != parent_of_group) { + if (parent_of_group != child_of_group) { + // This child's parent must be adjusted + parent_of_child->removeChild(child_of_group); + // Insert the child at the correct position according to the order of the children returned + // by claimChildren + if (group_index <= parent_of_group->childCount()) + parent_of_group->insertChild(group_index, child_of_group); + else + parent_of_group->addChild(child_of_group); + group_index++; + } else { + Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Object references to itself.\n"); + } + } else { + // The child already in the right group, but we may need to ajust it's index to follow the order of claimChildren + int index=parent_of_group->indexOfChild (child_of_group); + if (index>group_index) { + parent_of_group->takeChild (index); + parent_of_group->insertChild (group_index, child_of_group); + } + group_index++; + } + } else { + Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): " + "'%s' claimed a top level object '%s' to be it's child.\n", objectName.c_str(), internalName); } } } @@ -973,20 +1025,20 @@ void DocumentItem::slotChangeObject(const Gui::ViewProviderDocumentObject& view) Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Group references unknown object.\n"); } } - } - // move all children which are not part of the group anymore to this item - int count = it->second->childCount(); - for (int i=0; i < count; i++) { - QTreeWidgetItem* child = it->second->child(i); - if (children.find(child) == children.end()) { - it->second->takeChild(i); - this->addChild(child); - } - } - // set the text label - std::string displayName = obj->Label.getValue(); - it->second->setText(0, QString::fromUtf8(displayName.c_str())); + // move all children which are not part of the group anymore to this item + int count = parent_of_group->childCount(); + for (int i=0; i < count; i++) { + QTreeWidgetItem* child = parent_of_group->child(i); + if (children.find(child) == children.end()) { + parent_of_group->takeChild(i); + this->addChild(child); + } + } + + // set the text label + std::string displayName = obj->Label.getValue(); + parent_of_group->setText(0, QString::fromUtf8(displayName.c_str())); } else { Base::Console().Warning("Gui::DocumentItem::slotChangedObject(): Cannot change unknown object.\n"); @@ -1032,11 +1084,17 @@ void DocumentItem::slotHighlightObject (const Gui::ViewProviderDocumentObject& o else jt->second->setData(0, Qt::BackgroundColorRole,QVariant()); break; + case Gui::LightBlue: + if(set) + jt->second->setBackgroundColor(0,QColor(230,230,255)); + else + jt->second->setData(0, Qt::BackgroundColorRole,QVariant()); + break; default: break; } - jt->second->setFont(0,f); + } void DocumentItem::slotExpandObject (const Gui::ViewProviderDocumentObject& obj,const Gui::TreeItemMode& mode) @@ -1073,7 +1131,22 @@ const Gui::Document* DocumentItem::document() const //void DocumentItem::markItem(const App::DocumentObject* Obj,bool mark) //{ -// // never call without Object! +// // never call without Object! +// assert(Obj); +// +// +// std::map::iterator pos; +// pos = ObjectMap.find(Obj->getNameInDocument()); +// if (pos != ObjectMap.end()) { +// QFont f = pos->second->font(0); +// f.setUnderline(mark); +// pos->second->setFont(0,f); +// } +//} + +//void DocumentItem::markItem(const App::DocumentObject* Obj,bool mark) +//{ +// // never call without Object! // assert(Obj); // // @@ -1185,7 +1258,7 @@ void DocumentItem::selectItems(void) // The document objects in 'objs' is a subset of the document objects stored // in 'items'. Since both arrays are sorted we get the wanted tree items in // linear time. - std::vector common; + std::vector common; std::vector::iterator item_it = items.begin(); for (std::vector::iterator it = objs.begin(); it != objs.end(); ++it) { item_it = std::find_if(item_it, items.end(), std::bind2nd(ObjectItem_Equal(), *it)); @@ -1197,7 +1270,7 @@ void DocumentItem::selectItems(void) // get all unselected items of the given document std::sort(common.begin(), common.end()); std::sort(items.begin(), items.end()); - std::vector diff; + std::vector diff; std::back_insert_iterator > biit(diff); std::set_difference(items.begin(), items.end(), common.begin(), common.end(), biit); @@ -1221,6 +1294,8 @@ std::vector DocumentItem::getAllParents(DocumentObjectItem* for (std::vector::iterator it = inlist.begin(); it != inlist.end(); ++it) { Gui::ViewProvider* vp = pDocument->getViewProvider(*it); + if(!vp) + continue; std::vector child = vp->claimChildren(); for (std::vector::iterator jt = child.begin(); jt != child.end(); ++jt) { if (*jt == obj) { @@ -1267,7 +1342,7 @@ void DocumentObjectItem::testStatus() App::DocumentObject* pObject = viewObject->getObject(); // if status has changed then continue - int currentStatus = + int currentStatus = ((pObject->isError() ? 1 : 0) << 2) | ((pObject->mustExecute() == 1 ? 1 : 0) << 1) | (viewObject->isShow() ? 1 : 0); @@ -1315,28 +1390,28 @@ void DocumentObjectItem::testStatus() QIcon::Mode mode = QIcon::Normal; if (currentStatus & 1) { // visible - // Note: By default the foreground, i.e. text color is invalid - // to make use of the default color of the tree widget's palette. - // If we temporarily set this color to dark and reset to an invalid - // color again we cannot do it with setTextColor() or setForeground(), - // respectively, because for any reason the color would always switch - // to black which will lead to unreadable text if the system background - // hss already a dark color. + // Note: By default the foreground, i.e. text color is invalid + // to make use of the default color of the tree widget's palette. + // If we temporarily set this color to dark and reset to an invalid + // color again we cannot do it with setTextColor() or setForeground(), + // respectively, because for any reason the color would always switch + // to black which will lead to unreadable text if the system background + // hss already a dark color. // However, it works if we set the appropriate role to an empty QVariant(). -#if QT_VERSION >= 0x040200 - this->setData(0, Qt::ForegroundRole,QVariant()); +#if QT_VERSION >= 0x040200 + this->setData(0, Qt::ForegroundRole,QVariant()); #else - this->setData(0, Qt::TextColorRole,QVariant()); -#endif - } - else { // invisible - QStyleOptionViewItem opt; - opt.initFrom(this->treeWidget()); -#if QT_VERSION >= 0x040200 + this->setData(0, Qt::TextColorRole,QVariant()); +#endif + } + else { // invisible + QStyleOptionViewItem opt; + opt.initFrom(this->treeWidget()); +#if QT_VERSION >= 0x040200 this->setForeground(0, opt.palette.color(QPalette::Disabled,QPalette::Text)); #else this->setTextColor(0, opt.palette.color(QPalette::Disabled,QPalette::Text); -#endif +#endif mode = QIcon::Disabled; } @@ -1360,6 +1435,15 @@ void DocumentObjectItem::testStatus() this->setIcon(0, icon_mod); } +bool DocumentObjectItem::allowDrop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos) +{ + return viewObject->allowDrop(objList,keys,mouseBts,pos); +} +void DocumentObjectItem::drop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos) +{ + viewObject->drop(objList,keys,mouseBts,pos); +} + void DocumentObjectItem::displayStatusInfo() { App::DocumentObject* Obj = viewObject->getObject(); diff --git a/src/Gui/Tree.h b/src/Gui/Tree.h index 9319e6bc7..f4ce69a0f 100644 --- a/src/Gui/Tree.h +++ b/src/Gui/Tree.h @@ -44,7 +44,8 @@ enum HighlightMode { Underlined, Italic , Overlined , Bold , - Blue + Blue , + LightBlue }; /// highlight modes for the tree items @@ -131,7 +132,7 @@ private: }; /** The link between the tree and a document. - * Every document in the application gets its associated DocumentItem which controls + * Every document in the application gets its associated DocumentItem which controls * the visibility and the functions of the document. * \author Jürgen Riegel */ @@ -185,7 +186,7 @@ private: }; /** The link between the tree and a document object. - * Every object in the document gets its associated DocumentObjectItem which controls + * Every object in the document gets its associated DocumentObjectItem which controls * the visibility and the functions of the object. * @author Werner Mayer */ @@ -202,6 +203,9 @@ public: void setData(int column, int role, const QVariant & value); bool isChildOfItem(DocumentObjectItem*); + bool allowDrop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos); + void drop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos); + protected: void slotChangeIcon(); void slotChangeToolTip(const QString&); diff --git a/src/Gui/View3DInventor.cpp b/src/Gui/View3DInventor.cpp index 691a2bd54..d9e3fc975 100644 --- a/src/Gui/View3DInventor.cpp +++ b/src/Gui/View3DInventor.cpp @@ -156,6 +156,7 @@ View3DInventor::View3DInventor(Gui::Document* pcDocument, QWidget* parent, // create the inventor widget and set the defaults _viewer->setDocument(this->_pcDocument); + _viewer->setDocument(this->_pcDocument); stack->addWidget(_viewer->getWidget()); // http://forum.freecadweb.org/viewtopic.php?f=3&t=6055&sid=150ed90cbefba50f1e2ad4b4e6684eba // describes a minor error but trying to fix it leads to a major issue diff --git a/src/Gui/View3DInventorViewer.cpp b/src/Gui/View3DInventorViewer.cpp index 0e2b4a515..2634a936b 100644 --- a/src/Gui/View3DInventorViewer.cpp +++ b/src/Gui/View3DInventorViewer.cpp @@ -127,6 +127,7 @@ #include "SoTouchEvents.h" #include "WinNativeGestureRecognizers.h" +#include "Document.h" //#define FC_LOGGING_CB @@ -513,16 +514,16 @@ void View3DInventorViewer::init() } catch (...) { Base::Console().Warning("Failed to set up gestures. Unknown error.\n"); } - + //create the cursors QBitmap cursor = QBitmap::fromData(QSize(ROTATE_WIDTH, ROTATE_HEIGHT), rotate_bitmap); QBitmap mask = QBitmap::fromData(QSize(ROTATE_WIDTH, ROTATE_HEIGHT), rotate_mask_bitmap); spinCursor = QCursor(cursor, mask, ROTATE_HOT_X, ROTATE_HOT_Y); - + cursor = QBitmap::fromData(QSize(ZOOM_WIDTH, ZOOM_HEIGHT), zoom_bitmap); mask = QBitmap::fromData(QSize(ZOOM_WIDTH, ZOOM_HEIGHT), zoom_mask_bitmap); zoomCursor = QCursor(cursor, mask, ZOOM_HOT_X, ZOOM_HOT_Y); - + cursor = QBitmap::fromData(QSize(PAN_WIDTH, PAN_HEIGHT), pan_bitmap); mask = QBitmap::fromData(QSize(PAN_WIDTH, PAN_HEIGHT), pan_mask_bitmap); panCursor = QCursor(cursor, mask, PAN_HOT_X, PAN_HOT_Y); @@ -566,9 +567,15 @@ View3DInventorViewer::~View3DInventorViewer() void View3DInventorViewer::setDocument(Gui::Document* pcDocument) { // write the document the viewer belongs to to the selection node + guiDocument = pcDocument; selectionRoot->pcDocument = pcDocument; } +Document* View3DInventorViewer::getDocument() { + return guiDocument; +} + + void View3DInventorViewer::initialize() { navigation = new CADNavigationStyle(); @@ -626,7 +633,7 @@ void View3DInventorViewer::removeViewProvider(ViewProvider* pcProvider) SoSeparator* root = pcProvider->getRoot(); - if (root) { + if (root && (pcViewProviderRoot->findChild(root) != -1)) { pcViewProviderRoot->removeChild(root); _ViewProviderMap.erase(root); } @@ -642,6 +649,7 @@ void View3DInventorViewer::removeViewProvider(ViewProvider* pcProvider) _ViewProviderSet.erase(pcProvider); } + SbBool View3DInventorViewer::setEditingViewProvider(Gui::ViewProvider* p, int ModNum) { if (this->editViewProvider) @@ -682,8 +690,9 @@ void View3DInventorViewer::setOverrideMode(const std::string& mode) overrideMode = mode; - for (std::set::iterator it = _ViewProviderSet.begin(); it != _ViewProviderSet.end(); ++it) - (*it)->setOverrideMode(mode); + auto views = getDocument()->getViewProvidersOfType(Gui::ViewProvider::getClassTypeId()); + for (auto view : views) + view->setOverrideMode(mode); } /// update override mode. doesn't affect providers @@ -857,7 +866,7 @@ void View3DInventorViewer::setSceneGraph(SoNode* root) SoSearchAction sa; sa.setNode(this->backlight); - //we want the rendered scene with all lights and cameras, viewer->getSceneGraph would return + //we want the rendered scene with all lights and cameras, viewer->getSceneGraph would return //the geometry scene only SoNode* scene = this->getSoRenderManager()->getSceneGraph(); if (scene && scene->getTypeId().isDerivedFrom(SoSeparator::getClassTypeId())) { @@ -1461,7 +1470,7 @@ void View3DInventorViewer::renderScene(void) for (std::list::iterator it = this->graphicsItems.begin(); it != this->graphicsItems.end(); ++it) (*it)->paintGL(); - + //fps rendering if (fpsEnabled) { std::stringstream stream; diff --git a/src/Gui/View3DInventorViewer.h b/src/Gui/View3DInventorViewer.h index 1c37d88bc..02b0e6add 100644 --- a/src/Gui/View3DInventorViewer.h +++ b/src/Gui/View3DInventorViewer.h @@ -341,7 +341,8 @@ public: NavigationStyle* navigationStyle() const; void setDocument(Gui::Document *pcDocument); - + Gui::Document* getDocument(); + virtual PyObject *getPyObject(void); protected: @@ -420,6 +421,7 @@ private: SbBool allowredir; std::string overrideMode; + Gui::Document* guiDocument = nullptr; ViewerEventFilter* viewerEventFilter; diff --git a/src/Gui/View3DPy.cpp b/src/Gui/View3DPy.cpp index 9f83361ef..84ce78b62 100644 --- a/src/Gui/View3DPy.cpp +++ b/src/Gui/View3DPy.cpp @@ -52,6 +52,8 @@ #include "View3DInventor.h" #include "View3DInventorViewer.h" #include "View3DViewerPy.h" +#include "ActiveObjectList.h" + #include #include @@ -64,6 +66,7 @@ #include #include +#include #include using namespace Gui; @@ -173,6 +176,9 @@ void View3DInventorPy::init_type() "Remove the DraggerCalback function from the coin node\n" "Possibles types :\n" "'addFinishCallback','addStartCallback','addMotionCallback','addValueChangedCallback'\n"); + add_varargs_method("setActiveObject", &View3DInventorPy::setActiveObject, "setActiveObject(name,object)\nadd or set a new active object"); + add_varargs_method("getActiveObject", &View3DInventorPy::getActiveObject, "getActiveObject(name)\nreturns the active object for the given type"); + } View3DInventorPy::View3DInventorPy(View3DInventor *vi) @@ -223,15 +229,22 @@ Py::Object View3DInventorPy::getattr(const char * attr) s_out << "Cannot access attribute '" << attr << "' of deleted object"; throw Py::RuntimeError(s_out.str()); } - else { - Py::Object obj = Py::PythonExtension::getattr(attr); - if (PyCFunction_Check(obj.ptr())) { - PyCFunctionObject* op = reinterpret_cast(obj.ptr()); - if (!pycxx_handler) - pycxx_handler = op->m_ml->ml_meth; - op->m_ml->ml_meth = method_varargs_ext_handler; - } - return obj; + else { + // see if a active object has the same name + App::DocumentObject *docObj = _view->getActiveObject(attr); + if (docObj){ + return Py::Object(docObj->getPyObject(),true); + }else{ + // else looking for a methode with the name and call it + Py::Object obj = Py::PythonExtension::getattr(attr); + if (PyCFunction_Check(obj.ptr())) { + PyCFunctionObject* op = reinterpret_cast(obj.ptr()); + if (!pycxx_handler) + pycxx_handler = op->m_ml->ml_meth; + op->m_ml->ml_meth = method_varargs_ext_handler; + } + return obj; + } } } @@ -464,7 +477,7 @@ Py::Object View3DInventorPy::viewRotateLeft(const Py::Tuple& args) SbRotation rot = cam->orientation.getValue(); SbVec3f vdir(0, 0, -1); rot.multVec(vdir, vdir); - SbRotation nrot(vdir,float( M_PI/2)); + SbRotation nrot(vdir, (float)M_PI/2); cam->orientation.setValue(rot*nrot); } catch (const Base::Exception& e) { @@ -490,7 +503,7 @@ Py::Object View3DInventorPy::viewRotateRight(const Py::Tuple& args) SbRotation rot = cam->orientation.getValue(); SbVec3f vdir(0, 0, -1); rot.multVec(vdir, vdir); - SbRotation nrot(vdir, float(-M_PI/2)); + SbRotation nrot(vdir, (float)-M_PI/2); cam->orientation.setValue(rot*nrot); } catch (const Base::Exception& e) { @@ -2116,47 +2129,83 @@ Py::Object View3DInventorPy::addDraggerCallback(const Py::Tuple& args) Py::Object View3DInventorPy::removeDraggerCallback(const Py::Tuple& args) { - PyObject* dragger; - char* type; - PyObject* method; - if (!PyArg_ParseTuple(args.ptr(), "OsO", &dragger,&type, &method)) - throw Py::Exception(); + PyObject* dragger; + char* type; + PyObject* method; + if (!PyArg_ParseTuple(args.ptr(), "OsO", &dragger, &type, &method)) + throw Py::Exception(); - //Check if dragger is a SoDragger object and cast - void* ptr = 0; - try { - Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoDragger *", dragger, &ptr, 0); - } - catch (const Base::Exception&) { - throw Py::Exception("The first argument must be of type SoDragger"); - } + //Check if dragger is a SoDragger object and cast + void* ptr = 0; + try { + Base::Interpreter().convertSWIGPointerObj("pivy.coin", "SoDragger *", dragger, &ptr, 0); + } + catch (const Base::Exception&) { + throw Py::Exception("The first argument must be of type SoDragger"); + } - SoDragger* drag = reinterpret_cast(ptr); - try { - if (strcmp(type,"addFinishCallback")==0) { - drag->removeFinishCallback(draggerCallback,method); - } - else if (strcmp(type,"addStartCallback")==0) { - drag->removeStartCallback(draggerCallback,method); - } - else if (strcmp(type,"addMotionCallback")==0) { - drag->removeMotionCallback(draggerCallback,method); - } - else if (strcmp(type,"addValueChangedCallback")==0) { - drag->removeValueChangedCallback(draggerCallback,method); - } - else { - std::string s; - std::ostringstream s_out; - s_out << type << " is not a valid dragger callback type"; - throw Py::Exception(s_out.str()); - } + SoDragger* drag = reinterpret_cast(ptr); + try { + if (strcmp(type, "addFinishCallback") == 0) { + drag->removeFinishCallback(draggerCallback, method); + } + else if (strcmp(type, "addStartCallback") == 0) { + drag->removeStartCallback(draggerCallback, method); + } + else if (strcmp(type, "addMotionCallback") == 0) { + drag->removeMotionCallback(draggerCallback, method); + } + else if (strcmp(type, "addValueChangedCallback") == 0) { + drag->removeValueChangedCallback(draggerCallback, method); + } + else { + std::string s; + std::ostringstream s_out; + s_out << type << " is not a valid dragger callback type"; + throw Py::Exception(s_out.str()); + } - callbacks.remove(method); - Py_DECREF(method); - return Py::Callable(method, false); - } - catch (const Py::Exception&) { - throw; - } + callbacks.remove(method); + Py_DECREF(method); + return Py::Callable(method, false); + } + catch (const Py::Exception&) { + throw; + } } + +Py::Object View3DInventorPy::setActiveObject(const Py::Tuple& args) +{ + PyObject* docObject = 0; + char* name; + + //allow reset of active object by setting "None" + if( args.length() == 2 && args.back() == Py::None() ) { + PyArg_Parse(args.front().ptr(), "s", &name); + _view->setActiveObject(NULL, name); + return Py::None(); + } + + if (!PyArg_ParseTuple(args.ptr(), "sO!", &name, &App::DocumentObjectPy::Type, &docObject)) + throw Py::Exception(); + + + if (docObject){ + App::DocumentObject* obj = static_cast(docObject)->getDocumentObjectPtr(); + _view->setActiveObject(obj, name); + } + return Py::None(); +} + +Py::Object View3DInventorPy::getActiveObject(const Py::Tuple& args) +{ + char* name; + if (!PyArg_ParseTuple(args.ptr(), "s", &name)) + throw Py::Exception(); + + App::DocumentObject* obj = _view->getActiveObject(name); + if(!obj) + return Py::None(); + + return Py::Object(obj->getPyObject()); +} \ No newline at end of file diff --git a/src/Gui/View3DPy.h b/src/Gui/View3DPy.h index b87f8fdf3..fd644b1eb 100644 --- a/src/Gui/View3DPy.h +++ b/src/Gui/View3DPy.h @@ -102,6 +102,8 @@ public: Py::Object hasAxisCross(const Py::Tuple&); Py::Object addDraggerCallback(const Py::Tuple&); Py::Object removeDraggerCallback(const Py::Tuple&); + Py::Object setActiveObject(const Py::Tuple&); + Py::Object getActiveObject(const Py::Tuple&); private: static void eventCallback(void * ud, SoEventCallback * n); diff --git a/src/Gui/ViewProvider.cpp b/src/Gui/ViewProvider.cpp index b4c54ec1e..894800357 100644 --- a/src/Gui/ViewProvider.cpp +++ b/src/Gui/ViewProvider.cpp @@ -32,6 +32,8 @@ # include # include # include +# include +# include #endif /// Here the FreeCAD includes sorted by Base,App,Gui...... @@ -60,9 +62,10 @@ using namespace Gui; PROPERTY_SOURCE_ABSTRACT(Gui::ViewProvider, App::PropertyContainer) -ViewProvider::ViewProvider() +ViewProvider::ViewProvider() : pcAnnotation(0) , pyViewObject(0) + , overrideMode("As Is") , _iActualMode(-1) , _iEditMode(-1) , viewOverrideMode(-1) @@ -144,6 +147,12 @@ void ViewProvider::setUpdatesEnabled (bool enable) _updateData = enable; } +void highlight(const HighlightMode& high) +{ + + +} + void ViewProvider::eventCallback(void * ud, SoEventCallback * node) { const SoEvent * ev = node->getEvent(); @@ -326,19 +335,27 @@ bool ViewProvider::isVisible() const } void ViewProvider::setOverrideMode(const std::string &mode) -{ - if (mode == "As Is") +{ + if (mode == "As Is") { viewOverrideMode = -1; + overrideMode = mode; + } else { std::map::const_iterator it = _sDisplayMaskModes.find(mode); if (it == _sDisplayMaskModes.end()) return; //view style not supported viewOverrideMode = (*it).second; + overrideMode = mode; } if (pcModeSwitch->whichChild.getValue() != -1) setModeSwitch(); } +const string ViewProvider::getOverrideMode() { + return overrideMode; +} + + void ViewProvider::setModeSwitch() { if (viewOverrideMode == -1) @@ -373,16 +390,32 @@ PyObject* ViewProvider::getPyObject() SoPickedPoint* ViewProvider::getPointOnRay(const SbVec2s& pos, const View3DInventorViewer* viewer) const { - // for convenience make a pick ray action to get the (potentially) picked entity in the provider + //first get the path to this node and calculate the current transformation + SoSearchAction sa; + sa.setNode(pcRoot); + sa.setSearchingAll(true); + sa.apply(viewer->getSoRenderManager()->getSceneGraph()); + SoGetMatrixAction gm(viewer->getSoRenderManager()->getViewportRegion()); + gm.apply(sa.getPath()); + + SoTransform* trans = new SoTransform; + trans->setMatrix(gm.getMatrix()); + trans->ref(); + + // build a temporary scenegraph only keeping this viewproviders nodes and the accumulated + // transformation SoSeparator* root = new SoSeparator; root->ref(); root->addChild(viewer->getSoRenderManager()->getCamera()); + root->addChild(trans); root->addChild(pcRoot); + //get the picked point SoRayPickAction rp(viewer->getSoRenderManager()->getViewportRegion()); rp.setPoint(pos); rp.apply(root); root->unref(); + trans->unref(); SoPickedPoint* pick = rp.getPickedPoint(); return (pick ? new SoPickedPoint(*pick) : 0); @@ -392,9 +425,33 @@ SoPickedPoint* ViewProvider::getPointOnRay(const SbVec3f& pos,const SbVec3f& dir { // Note: There seems to be a bug with setRay() which causes SoRayPickAction // to fail to get intersections between the ray and a line + + //first get the path to this node and calculate the current setTransformation + SoSearchAction sa; + sa.setNode(pcRoot); + sa.setSearchingAll(true); + sa.apply(viewer->getSoRenderManager()->getSceneGraph()); + SoGetMatrixAction gm(viewer->getSoRenderManager()->getViewportRegion()); + gm.apply(sa.getPath()); + + // build a temporary scenegraph only keeping this viewproviders nodes and the accumulated + // transformation + SoTransform* trans = new SoTransform; + trans->ref(); + trans->setMatrix(gm.getMatrix()); + + SoSeparator* root = new SoSeparator; + root->ref(); + root->addChild(viewer->getSoRenderManager()->getCamera()); + root->addChild(trans); + root->addChild(pcRoot); + + //get the picked point SoRayPickAction rp(viewer->getSoRenderManager()->getViewportRegion()); rp.setRay(pos,dir); - rp.apply(pcRoot); + rp.apply(root); + root->unref(); + trans->unref(); // returns a copy of the point SoPickedPoint* pick = rp.getPickedPoint(); diff --git a/src/Gui/ViewProvider.h b/src/Gui/ViewProvider.h index 694d72b27..2bab337eb 100644 --- a/src/Gui/ViewProvider.h +++ b/src/Gui/ViewProvider.h @@ -108,7 +108,7 @@ public: { return std::vector(); } /** @name Selection handling - * This group of methodes do the selection handling. + * This group of methods do the selection handling. * Here you can define how the selection for your ViewProfider * works. */ @@ -125,8 +125,13 @@ public: /// return the higlight lines for a given element or the whole shape virtual std::vector getSelectionShape(const char* Element) const { return std::vector(); } - /// get called if the object is about to get deleted. Here you can delete other objects to or switch visibility of others. - virtual bool onDelete(const std::vector &) + /** + * Get called if the object is about to get deleted. + * Here you can delete other objects, switch their visibility or prevent the deletion of the object. + * @param subNames list of selected subelements + * @return true if the deletion is approoved by the view provider. + */ + virtual bool onDelete(const std::vector &subNames) { return true;} //@} @@ -165,6 +170,11 @@ public: /** Check whether the object can be removed from the view provider by drag and drop */ virtual bool canDragObject(App::DocumentObject*) const { return true; } + /** Tell the tree view if this object should apear there */ + virtual bool showInTree() const + { + return true; + } /** Remove a child from the view provider by drag and drop */ virtual void dragObject(App::DocumentObject*) { } @@ -190,7 +200,7 @@ public: //@} /** update the content of the ViewProvider - * this method have to implement the recalcualtion + * this method have to implement the recalculation * of the ViewProvider. There are different reasons to * update. E.g. only the view attribute has changed, or * the data has manipulated. @@ -223,6 +233,7 @@ public: bool isVisible() const; /// Overrides the display mode with mode. virtual void setOverrideMode(const std::string &mode); + const std::string getOverrideMode(); //@} @@ -338,6 +349,7 @@ protected: /// The root separator for annotations SoSeparator *pcAnnotation; ViewProviderPy* pyViewObject; + std::string overrideMode; private: void setModeSwitch(); diff --git a/src/Gui/ViewProviderDocumentObject.cpp b/src/Gui/ViewProviderDocumentObject.cpp index a3a650e02..62c33bb63 100644 --- a/src/Gui/ViewProviderDocumentObject.cpp +++ b/src/Gui/ViewProviderDocumentObject.cpp @@ -247,3 +247,11 @@ PyObject* ViewProviderDocumentObject::getPyObject() pyViewObject->IncRef(); return pyViewObject; } + +bool ViewProviderDocumentObject::allowDrop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos) +{ + return false; +} +void ViewProviderDocumentObject::drop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos) +{ +} diff --git a/src/Gui/ViewProviderDocumentObject.h b/src/Gui/ViewProviderDocumentObject.h index 924dff83c..3b567a540 100644 --- a/src/Gui/ViewProviderDocumentObject.h +++ b/src/Gui/ViewProviderDocumentObject.h @@ -89,6 +89,15 @@ public: virtual void finishRestoring(); //@} + /** @name drag & drop handling */ + //@{ + /// get called if the user hover over a object in the tree + virtual bool allowDrop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos); + /// get called if the user drops some objects + virtual void drop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos); + //@} + + protected: /*! Get the active mdi view of the document this view provider is part of. @note The returned mdi view doesn't need to be a 3d view but can be e.g. diff --git a/src/Gui/ViewProviderDocumentObjectGroup.cpp b/src/Gui/ViewProviderDocumentObjectGroup.cpp index bec1cb7e6..8ef22da3a 100644 --- a/src/Gui/ViewProviderDocumentObjectGroup.cpp +++ b/src/Gui/ViewProviderDocumentObjectGroup.cpp @@ -26,6 +26,7 @@ #ifndef _PreComp_ # include # include +# include #endif #include @@ -131,7 +132,10 @@ bool ViewProviderDocumentObjectGroup::canDragObjects() const void ViewProviderDocumentObjectGroup::dragObject(App::DocumentObject* obj) { - static_cast(getObject())->removeObject(obj); + Gui::Command::doCommand(Gui::Command::Doc,"App.getDocument(\"%s\").getObject(\"%s\").removeObject(" + "App.getDocument(\"%s\").getObject(\"%s\"))", + getObject()->getDocument()->getName(), getObject()->getNameInDocument(), + obj->getDocument()->getName(), obj->getNameInDocument() ); } bool ViewProviderDocumentObjectGroup::canDropObjects() const @@ -141,7 +145,10 @@ bool ViewProviderDocumentObjectGroup::canDropObjects() const void ViewProviderDocumentObjectGroup::dropObject(App::DocumentObject* obj) { - static_cast(getObject())->addObject(obj); + Gui::Command::doCommand(Gui::Command::Doc,"App.getDocument(\"%s\").getObject(\"%s\").addObject(" + "App.getDocument(\"%s\").getObject(\"%s\"))", + getObject()->getDocument()->getName(), getObject()->getNameInDocument(), + obj->getDocument()->getName(), obj->getNameInDocument() ); } std::vector ViewProviderDocumentObjectGroup::getDisplayModes(void) const @@ -152,11 +159,71 @@ std::vector ViewProviderDocumentObjectGroup::getDisplayModes(void) bool ViewProviderDocumentObjectGroup::onDelete(const std::vector &) { - Gui::Command::doCommand(Gui::Command::Doc,"App.getDocument(\"%s\").getObject(\"%s\").removeObjectsFromDocument()" - ,getObject()->getDocument()->getName(), getObject()->getNameInDocument()); + App::DocumentObjectGroup *group = static_cast (getObject()); + // If the group is nonempty ask the user if he wants to delete it's content + if ( group->Group.getSize () ) { + QMessageBox::StandardButton choice = + QMessageBox::question ( 0, QObject::tr ( "Delete group content?" ), + QObject::tr ( "The %1 is not empty, delete it's content as well?") + .arg ( QString::fromUtf8 ( group->Label.getValue () ) ), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes ); + + if ( choice == QMessageBox::Yes ) { + Gui::Command::doCommand(Gui::Command::Doc, + "App.getDocument(\"%s\").getObject(\"%s\").removeObjectsFromDocument()" + ,getObject()->getDocument()->getName(), getObject()->getNameInDocument()); + } + } return true; } +bool ViewProviderDocumentObjectGroup::allowDrop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos) +{ + for( std::vector::const_iterator it = objList.begin();it!=objList.end();++it) + if ((*it)->getTypeId().isDerivedFrom(App::DocumentObjectGroup::getClassTypeId())) { + if (static_cast(getObject())->isChildOf( + static_cast(*it))) { + return false; + } + } + + return true; +} +void ViewProviderDocumentObjectGroup::drop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos) +{ + // Open command + App::DocumentObjectGroup* grp = static_cast(getObject()); + App::Document* doc = grp->getDocument(); + Gui::Document* gui = Gui::Application::Instance->getDocument(doc); + gui->openCommand("Move object"); + for( std::vector::const_iterator it = objList.begin();it!=objList.end();++it) { + // get document object + const App::DocumentObject* obj = *it; + const App::DocumentObjectGroup* par = App::DocumentObjectGroup::getGroupOfObject(obj); + if (par) { + // allow an object to be in one group only + QString cmd; + cmd = QString::fromAscii("App.getDocument(\"%1\").getObject(\"%2\").removeObject(" + "App.getDocument(\"%1\").getObject(\"%3\"))") + .arg(QString::fromAscii(doc->getName())) + .arg(QString::fromAscii(par->getNameInDocument())) + .arg(QString::fromAscii(obj->getNameInDocument())); + Gui::Application::Instance->runPythonCode(cmd.toUtf8()); + } + + // build Python command for execution + QString cmd; + cmd = QString::fromAscii("App.getDocument(\"%1\").getObject(\"%2\").addObject(" + "App.getDocument(\"%1\").getObject(\"%3\"))") + .arg(QString::fromAscii(doc->getName())) + .arg(QString::fromAscii(grp->getNameInDocument())) + .arg(QString::fromAscii(obj->getNameInDocument())); + + Gui::Application::Instance->runPythonCode(cmd.toUtf8()); + } + gui->commitCommand(); + +} void ViewProviderDocumentObjectGroup::hide(void) { diff --git a/src/Gui/ViewProviderDocumentObjectGroup.h b/src/Gui/ViewProviderDocumentObjectGroup.h index 5ba06eae9..abbc5b3fb 100644 --- a/src/Gui/ViewProviderDocumentObjectGroup.h +++ b/src/Gui/ViewProviderDocumentObjectGroup.h @@ -52,12 +52,17 @@ public: QIcon getIcon(void) const; /// returns a list of all possible modes std::vector getDisplayModes(void) const; - void hide(void); - void show(void); + virtual void hide(void); + virtual void show(void); bool isShow(void) const; virtual bool onDelete(const std::vector &); + /// get called if the user hover over a object in the tree + virtual bool allowDrop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos); + /// get called if the user drops some objects + virtual void drop(const std::vector &objList,Qt::KeyboardModifiers keys,Qt::MouseButtons mouseBts,const QPoint &pos); + protected: /// get called by the container whenever a property has been changed void onChanged(const App::Property* prop); diff --git a/src/Gui/ViewProviderGeoFeatureGroup.cpp b/src/Gui/ViewProviderGeoFeatureGroup.cpp new file mode 100644 index 000000000..47b6fef04 --- /dev/null +++ b/src/Gui/ViewProviderGeoFeatureGroup.cpp @@ -0,0 +1,101 @@ +/*************************************************************************** + * Copyright (c) 2011 Juergen Riegel * + * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +#endif + +#include + +#include "ViewProviderGeoFeatureGroup.h" + + +using namespace Gui; + + +PROPERTY_SOURCE(Gui::ViewProviderGeoFeatureGroup, Gui::ViewProviderDocumentObjectGroup) + +ViewProviderGeoFeatureGroup::ViewProviderGeoFeatureGroup() +{ + pcGroupChildren = new SoGroup(); + pcGroupChildren->ref(); +} + +ViewProviderGeoFeatureGroup::~ViewProviderGeoFeatureGroup() +{ + pcGroupChildren->unref(); + pcGroupChildren = 0; +} + +std::vector ViewProviderGeoFeatureGroup::claimChildren3D(void) const { + return static_cast(getObject())->getGeoSubObjects (); +} + +void ViewProviderGeoFeatureGroup::attach(App::DocumentObject* pcObject) +{ + Gui::ViewProviderDocumentObjectGroup::attach(pcObject); + addDisplayMaskMode(pcGroupChildren, "Group"); +} + +void ViewProviderGeoFeatureGroup::setDisplayMode(const char* ModeName) +{ + if ( strcmp("Group",ModeName)==0 ) + setDisplayMaskMode("Group"); + + ViewProviderDocumentObjectGroup::setDisplayMode( ModeName ); +} + +std::vector ViewProviderGeoFeatureGroup::getDisplayModes(void) const +{ + // get the modes of the father + std::vector StrList = ViewProviderDocumentObjectGroup::getDisplayModes(); + + // add your own modes + StrList.push_back("Group"); + + return StrList; +} + +void ViewProviderGeoFeatureGroup::updateData(const App::Property* prop) +{ + App::GeoFeatureGroup *obj = static_cast ( getObject() ); + if (prop == &obj->Placement) { + setTransformation ( obj->Placement.getValue().toMatrix() ); + } else { + ViewProviderDocumentObjectGroup::updateData ( prop ); + } +} + +// Python feature ----------------------------------------------------------------------- + +namespace Gui { +/// @cond DOXERR +PROPERTY_SOURCE_TEMPLATE(Gui::ViewProviderGeoFeatureGroupPython, Gui::ViewProviderGeoFeatureGroup) +/// @endcond + +// explicit template instantiation +template class GuiExport ViewProviderPythonFeatureT; +} diff --git a/src/Gui/ViewProviderGeoFeatureGroup.h b/src/Gui/ViewProviderGeoFeatureGroup.h new file mode 100644 index 000000000..33a5e2c6a --- /dev/null +++ b/src/Gui/ViewProviderGeoFeatureGroup.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (c) 2011 Juergen Riegel * + * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDER_ViewProviderGeoFeatureGroup_H +#define GUI_VIEWPROVIDER_ViewProviderGeoFeatureGroup_H + + +#include "ViewProviderDocumentObjectGroup.h" + +namespace Gui { + +class GuiExport ViewProviderGeoFeatureGroup : public ViewProviderDocumentObjectGroup +{ + PROPERTY_HEADER(Gui::ViewProviderGeoFeatureGroup); + +public: + /// constructor. + ViewProviderGeoFeatureGroup(); + /// destructor. + virtual ~ViewProviderGeoFeatureGroup(); + + virtual std::vector claimChildren3D(void)const; + + virtual SoGroup* getChildRoot(void) const {return pcGroupChildren;}; + + virtual void attach(App::DocumentObject* pcObject); + virtual void setDisplayMode(const char* ModeName); + virtual std::vector getDisplayModes(void) const; + + /// Show the object in the view: suppresses behavior of DocumentObjectGroup + virtual void show(void) { + ViewProviderDocumentObject::show(); + } + /// Hide the object in the view: suppresses behavior of DocumentObjectGroup + virtual void hide(void) { + ViewProviderDocumentObject::hide(); + } + + virtual void updateData(const App::Property*); +protected: + SoGroup *pcGroupChildren; +}; + +typedef ViewProviderPythonFeatureT ViewProviderGeoFeatureGroupPython; + +} // namespace Gui + +#endif // GUI_VIEWPROVIDER_DOCUMENTOBJECTGROUP_H + diff --git a/src/Gui/ViewProviderLine.cpp b/src/Gui/ViewProviderLine.cpp new file mode 100644 index 000000000..cebaed04c --- /dev/null +++ b/src/Gui/ViewProviderLine.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2012 * + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +#endif + +#include "ViewProviderOrigin.h" + +#include "ViewProviderLine.h" + +using namespace Gui; + +PROPERTY_SOURCE(Gui::ViewProviderLine, Gui::ViewProviderOriginFeature) + + +ViewProviderLine::ViewProviderLine() +{ } + +ViewProviderLine::~ViewProviderLine() +{ } + +void ViewProviderLine::attach ( App::DocumentObject *obj ) { + ViewProviderOriginFeature::attach ( obj ); + + static const float size = ViewProviderOrigin::defaultSize (); + + static const SbVec3f verts[2] = { SbVec3f(size, 0, 0), SbVec3f ( -size, 0, 0 ) }; + + // indexes used to create the edges + static const int32_t lines[4] = { 0, 1, -1 }; + + SoSeparator *sep = getOriginFeatureRoot (); + + SoCoordinate3 *pCoords = new SoCoordinate3 (); + pCoords->point.setNum (2); + pCoords->point.setValues ( 0, 2, verts ); + sep->addChild ( pCoords ); + + SoIndexedLineSet *pLines = new SoIndexedLineSet (); + pLines->ref(); + pLines->coordIndex.setNum(3); + pLines->coordIndex.setValues(0, 3, lines); + sep->addChild ( pLines ); + + SoTranslation *textTranslation = new SoTranslation (); + textTranslation->ref (); + textTranslation->translation.setValue ( SbVec3f ( -size * 49. / 50., size / 30., 0 ) ); + sep->addChild ( textTranslation ); + + sep->addChild ( getLabel () ); +} diff --git a/src/Gui/ViewProviderLine.h b/src/Gui/ViewProviderLine.h new file mode 100644 index 000000000..b7fc8a86a --- /dev/null +++ b/src/Gui/ViewProviderLine.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2012 * + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef GUI_ViewProviderLine_H +#define GUI_ViewProviderLine_H + +#include "ViewProviderOriginFeature.h" + +namespace Gui +{ + +class GuiExport ViewProviderLine : public ViewProviderOriginFeature { + PROPERTY_HEADER(Gui::ViewProviderLine); +public: + /// Constructor + ViewProviderLine(void); + virtual ~ViewProviderLine(); + + virtual void attach ( App::DocumentObject * ); +}; + +} //namespace Gui + + +#endif // GUI_ViewProviderLine_H diff --git a/src/Gui/ViewProviderOrigin.cpp b/src/Gui/ViewProviderOrigin.cpp new file mode 100644 index 000000000..295b44b57 --- /dev/null +++ b/src/Gui/ViewProviderOrigin.cpp @@ -0,0 +1,217 @@ +/*************************************************************************** + * Copyright (c) Stefan Tröger (stefantroeger@gmx.net) 2015 * + * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +# include +# include +#endif + + +#include +#include +#include +#include + +/// Here the FreeCAD includes sorted by Base,App,Gui...... +#include "ViewProviderOrigin.h" +#include "ViewProviderPlane.h" +#include "ViewProviderLine.h" +#include "Application.h" +#include "Command.h" +#include "BitmapFactory.h" +#include "Document.h" +#include "Tree.h" +#include "View3DInventor.h" +#include "View3DInventorViewer.h" + +#include "Base/Console.h" + +#include + +using namespace Gui; + + +PROPERTY_SOURCE(Gui::ViewProviderOrigin, Gui::ViewProviderDocumentObject) + +/** + * Creates the view provider for an object group. + */ +ViewProviderOrigin::ViewProviderOrigin() +{ + ADD_PROPERTY_TYPE ( Size, (Base::Vector3d(10,10,10)), 0, App::Prop_ReadOnly, + "The displayed size of the origin" ); + + sPixmap = "CoordinateSystem"; + Visibility.setValue(false); + + pcGroupChildren = new SoGroup(); + pcGroupChildren->ref(); +} + +ViewProviderOrigin::~ViewProviderOrigin() { + pcGroupChildren->unref(); + pcGroupChildren = 0; +} + +std::vector ViewProviderOrigin::claimChildren(void) const { + return static_cast( getObject() )->OriginFeatures.getValues (); +} + +std::vector ViewProviderOrigin::claimChildren3D(void) const { + return claimChildren (); +} + +void ViewProviderOrigin::attach(App::DocumentObject* pcObject) +{ + Gui::ViewProviderDocumentObject::attach(pcObject); + addDisplayMaskMode(pcGroupChildren, "Base"); +} + +std::vector ViewProviderOrigin::getDisplayModes(void) const +{ + return { "Base" }; +} + +void ViewProviderOrigin::setDisplayMode(const char* ModeName) +{ + if (strcmp(ModeName, "Base") == 0) + setDisplayMaskMode("Base"); + ViewProviderDocumentObject::setDisplayMode(ModeName); +} + +void ViewProviderOrigin::setTemporaryVisibility(bool axis, bool plane) { + App::Origin* origin = static_cast( getObject() ); + + bool saveState = tempVisMap.empty(); + + try { + // Remember & Set axis visability + for(App::DocumentObject* obj : origin->axes()) { + if (obj) { + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(obj); + if(vp) { + if (saveState) { + tempVisMap[vp] = vp->isVisible(); + } + vp->setVisible(axis); + } + } + } + + // Remember & Set plane visability + for(App::DocumentObject* obj : origin->planes()) { + if (obj) { + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(obj); + if(vp) { + if (saveState) { + tempVisMap[vp] = vp->isVisible(); + } + vp->setVisible(plane); + } + } + } + } catch (const Base::Exception &ex) { + Base::Console().Error ("%s\n", ex.what() ); + } + + // Remember & Set self visability + tempVisMap[this] = isVisible(); + setVisible(true); + +} + +void ViewProviderOrigin::resetTemporaryVisibility() { + for(std::pair pair : tempVisMap) { + pair.first->setVisible(pair.second); + } + tempVisMap.clear (); +} + +bool ViewProviderOrigin::isTemporaryVisibility() { + return !tempVisMap.empty(); +} + +void ViewProviderOrigin::onChanged(const App::Property* prop) { + if (prop == &Size) { + try { + Gui::Application *app = Gui::Application::Instance; + Base::Vector3d sz = Size.getValue (); + App::Origin* origin = static_cast ( getObject() ); + + // Calculate axes and planes sizes + double szXY = std::max ( sz.x, sz.y ); + double szXZ = std::max ( sz.x, sz.z ); + double szYZ = std::max ( sz.y, sz.z ); + + double szX = std::min ( szXY, szXZ ); + double szY = std::min ( szXY, szYZ ); + double szZ = std::min ( szXZ, szYZ ); + + // Find view providers + Gui::ViewProviderPlane* vpPlaneXY, *vpPlaneXZ, *vpPlaneYZ; + Gui::ViewProviderLine* vpLineX, *vpLineY, *vpLineZ; + // Planes + vpPlaneXY = static_cast ( app->getViewProvider ( origin->getXY () ) ); + vpPlaneXZ = static_cast ( app->getViewProvider ( origin->getXZ () ) ); + vpPlaneYZ = static_cast ( app->getViewProvider ( origin->getYZ () ) ); + // Axes + vpLineX = static_cast ( app->getViewProvider ( origin->getX () ) ); + vpLineY = static_cast ( app->getViewProvider ( origin->getY () ) ); + vpLineZ = static_cast ( app->getViewProvider ( origin->getZ () ) ); + + // set their sizes + if (vpPlaneXY) { vpPlaneXY->Size.setValue ( szXY ); } + if (vpPlaneXZ) { vpPlaneXZ->Size.setValue ( szXZ ); } + if (vpPlaneYZ) { vpPlaneYZ->Size.setValue ( szYZ ); } + if (vpLineX) { vpLineX->Size.setValue ( szX ); } + if (vpLineY) { vpLineY->Size.setValue ( szY ); } + if (vpLineZ) { vpLineZ->Size.setValue ( szZ ); } + + } catch (const Base::Exception &ex) { + Base::Console().Error ("%s\n", ex.what() ); + } + } + + ViewProviderDocumentObject::onChanged ( prop ); +} + +bool ViewProviderOrigin::onDelete(const std::vector &) { + App::Origin* origin = static_cast( getObject() ); + + if ( !origin->getInList().empty() ) { + return false; + } + + for (auto obj: origin->OriginFeatures.getValues() ) { + Gui::Command::doCommand( Gui::Command::Doc, "App.getDocument(\"%s\").removeObject(\"%s\")", + obj->getDocument()->getName(), obj->getNameInDocument() ); + } + + return true; +} diff --git a/src/Gui/ViewProviderOrigin.h b/src/Gui/ViewProviderOrigin.h new file mode 100644 index 000000000..67034099c --- /dev/null +++ b/src/Gui/ViewProviderOrigin.h @@ -0,0 +1,88 @@ +/*************************************************************************** + * Copyright (c) Stefan Tröger (stefantroeger@gmx.net) 2015 * + * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDER_ViewProviderOrigin_H +#define GUI_VIEWPROVIDER_ViewProviderOrigin_H + +#include + +#include "ViewProviderDocumentObject.h" + +namespace Gui { + +class Document; + +class GuiExport ViewProviderOrigin : public ViewProviderDocumentObject +{ + PROPERTY_HEADER(Gui::ViewProviderOrigin); + +public: + /// Size of the origin as setted by the part. + App::PropertyVector Size; + + /// constructor. + ViewProviderOrigin(); + /// destructor. + virtual ~ViewProviderOrigin(); + + /// @name Override methodes + ///@{ + virtual std::vector claimChildren(void) const; + virtual std::vector claimChildren3D(void) const; + + virtual SoGroup* getChildRoot(void) const {return pcGroupChildren;}; + + virtual void attach(App::DocumentObject* pcObject); + virtual std::vector getDisplayModes(void) const; + virtual void setDisplayMode(const char* ModeName); + ///@} + + /** @name Temporary visability mode + * Control the visability of origin and associated objects when needed + */ + ///@{ + /// Set temporary visability of some of origin's objects e.g. while rotating or mirroring + void setTemporaryVisibility (bool axis, bool planes); + /// Returns true if the origin in temporary visability mode + bool isTemporaryVisibility (); + /// Reset the visability + void resetTemporaryVisibility (); + ///@} + + /// Returns default size. Use this if it is not possible to determin apropriate size by other means + static double defaultSize() {return 10.;} +protected: + virtual void onChanged(const App::Property* prop); + virtual bool onDelete(const std::vector &); + +private: + SoGroup *pcGroupChildren; + + std::map tempVisMap; +}; + +} // namespace Gui + +#endif // GUI_VIEWPROVIDER_DOCUMENTOBJECTGROUP_H + diff --git a/src/Gui/ViewProviderOriginFeature.cpp b/src/Gui/ViewProviderOriginFeature.cpp new file mode 100644 index 000000000..783ba6e9d --- /dev/null +++ b/src/Gui/ViewProviderOriginFeature.cpp @@ -0,0 +1,190 @@ +/*************************************************************************** + * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include +#include + +#include "SoFCSelection.h" +#include "Window.h" +#include "ViewProviderOrigin.h" + +#include "ViewProviderOriginFeature.h" + +using namespace Gui; + +PROPERTY_SOURCE(Gui::ViewProviderOriginFeature, Gui::ViewProviderGeometryObject) + +ViewProviderOriginFeature::ViewProviderOriginFeature () { + ADD_PROPERTY_TYPE ( Size, (ViewProviderOrigin::defaultSize()), 0, App::Prop_ReadOnly, + "Visual size of the feature" ); + + ShapeColor.setValue ( 50./255, 150./255, 250./255 ); // Set default color for origin (light-blue) + BoundingBox.setStatus(App::Property::Hidden, true); // Hide Boundingbox from the user due to it doesn't make sence + + // Create node for scaling the origin + pScale = new SoScale (); + pScale->ref (); + + // Create the separator filled by inherited classes + pOriginFeatureRoot = new SoSeparator(); + pOriginFeatureRoot->ref (); + + // Create the Label node + pLabel = new SoAsciiText(); + pLabel->ref(); + pLabel->width.setValue(-1); + + sPixmap = "view-measurement"; +} + + +ViewProviderOriginFeature::~ViewProviderOriginFeature () { + pScale->unref (); + pOriginFeatureRoot->unref (); + pLabel->unref (); +} + + +void ViewProviderOriginFeature::attach(App::DocumentObject* pcObject) +{ + ViewProviderGeometryObject::attach(pcObject); + + float defaultSz = ViewProviderOrigin::defaultSize(); + float sz = Size.getValue () / defaultSz; + + // Create an external separator + SoSeparator *sep = new SoSeparator(); + + // Add material from the base class + sep->addChild(pcShapeMaterial); + + // Bind same material to all part + SoMaterialBinding* matBinding = new SoMaterialBinding; + matBinding->value = SoMaterialBinding::OVERALL; + sep->addChild(matBinding); + + // Scale feature to the given size + pScale->scaleFactor = SbVec3f (sz, sz, sz); + sep->addChild (pScale); + + // Setup font size + SoFont *font = new SoFont (); + font->size.setValue ( defaultSz/10.); + sep->addChild ( font ); + + // Create the selection node + SoFCSelection *highlight = new SoFCSelection (); + highlight->applySettings (); + if ( !Selectable.getValue() ) { + highlight->selectionMode = Gui::SoFCSelection::SEL_OFF; + } + highlight->objectName = getObject()->getNameInDocument(); + highlight->documentName = getObject()->getDocument()->getName(); + highlight->style = SoFCSelection::EMISSIVE_DIFFUSE; + + // Style for normal (visiable) lines + SoDrawStyle* style = new SoDrawStyle (); + style->lineWidth = 2.0f; + highlight->addChild ( style ); + + // Visible lines + highlight->addChild ( pOriginFeatureRoot ); + + // Hidden features + SoAnnotation *hidden = new SoAnnotation (); + + // Style for hidden lines + style = new SoDrawStyle (); + style->lineWidth = 2.0f; + style->linePattern.setValue ( 0xF000 ); // (dash-skip-skip-skip) + hidden->addChild ( style ); + + // Hidden lines + hidden->addChild ( pOriginFeatureRoot ); + + highlight->addChild ( hidden ); + + sep->addChild ( highlight ); + + // Setup the object label as it's text + pLabel->string.setValue ( SbString ( pcObject->Label.getValue () ) ); + + addDisplayMaskMode ( sep, "Base" ); +} + +void ViewProviderOriginFeature::updateData ( const App::Property* prop ) { + if (prop == &getObject()->Label) { + pLabel->string.setValue ( SbString ( getObject()->Label.getValue () ) ); + } + ViewProviderGeometryObject::updateData(prop); +} + +void ViewProviderOriginFeature::onChanged ( const App::Property* prop ) { + if (prop == &Size) { + float sz = Size.getValue () / ViewProviderOrigin::defaultSize(); + pScale->scaleFactor = SbVec3f (sz, sz, sz); + } + ViewProviderGeometryObject::onChanged(prop); +} + +std::vector ViewProviderOriginFeature::getDisplayModes () const +{ + // add modes + std::vector StrList; + StrList.push_back("Base"); + return StrList; +} + +void ViewProviderOriginFeature::setDisplayMode (const char* ModeName) +{ + if (strcmp(ModeName, "Base") == 0) + setDisplayMaskMode("Base"); + ViewProviderGeometryObject::setDisplayMode(ModeName); +} + +bool ViewProviderOriginFeature::onDelete(const std::vector &) { + App::OriginFeature *feat = static_cast ( getObject() ); + // Forbid deletion if there is an origin thes feature belongs to + + if ( feat->getOrigin () ) { + return false; + } else { + return true; + } +} diff --git a/src/Gui/ViewProviderOriginFeature.h b/src/Gui/ViewProviderOriginFeature.h new file mode 100644 index 000000000..7bdde1568 --- /dev/null +++ b/src/Gui/ViewProviderOriginFeature.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (c) 2015 Alexander Golubev (Fat-Zer) * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef VIEWPROVIDEORIGINFEATURE_H_BYJRZNDL +#define VIEWPROVIDEORIGINFEATURE_H_BYJRZNDL + +#include "ViewProviderGeometryObject.h" + +class SoAsciiText; +class SoScale; + +namespace Gui +{ + +/** + * View provider associated with an App::OriginFeature. + */ +class GuiExport ViewProviderOriginFeature: public ViewProviderGeometryObject { + PROPERTY_HEADER(Gui::ViewProviderOriginFeature); + +public: + /// The display size of the feature + App::PropertyFloat Size; + + ViewProviderOriginFeature (); + virtual ~ViewProviderOriginFeature (); + + /// Get point derived classes will add their specific stuff + SoSeparator * getOriginFeatureRoot () { return pOriginFeatureRoot; } + + /// Get pointer to the text label associated with the feature + SoAsciiText * getLabel () { return pLabel; } + + virtual void attach(App::DocumentObject *); + virtual void updateData(const App::Property *); + virtual std::vector getDisplayModes () const; + virtual void setDisplayMode (const char* ModeName); + + /// @name Suppress ViewProviderGeometryObject's behaviour + ///@{ + virtual bool setEdit ( int ) + { return false; } + virtual void unsetEdit ( int ) + { } + ///@} + +protected: + virtual void onChanged ( const App::Property* prop ); + virtual bool onDelete ( const std::vector & ); +protected: + SoSeparator * pOriginFeatureRoot; + SoScale * pScale; + SoAsciiText * pLabel; +}; + +} /* Gui */ + +#endif /* end of include guard: VIEWPROVIDEORIGINFEATURE_H_BYJRZNDL */ diff --git a/src/Gui/ViewProviderOriginGroup.cpp b/src/Gui/ViewProviderOriginGroup.cpp new file mode 100644 index 000000000..cd24b299c --- /dev/null +++ b/src/Gui/ViewProviderOriginGroup.cpp @@ -0,0 +1,189 @@ +/*************************************************************************** + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +#endif + +#include +#include +#include + +#include "Application.h" +#include "Document.h" +#include "View3DInventor.h" +#include "View3DInventorViewer.h" +#include "ViewProviderOrigin.h" +#include "ViewProviderOriginFeature.h" + +#include "ViewProviderOriginGroup.h" + + +using namespace Gui; + + +PROPERTY_SOURCE(Gui::ViewProviderOriginGroup, Gui::ViewProviderGeoFeatureGroup) + +ViewProviderOriginGroup::ViewProviderOriginGroup () +{ } + +ViewProviderOriginGroup::~ViewProviderOriginGroup () { + connectChangedObjectApp.disconnect(); + connectChangedObjectGui.disconnect(); +} + +std::vector ViewProviderOriginGroup::constructChildren ( + const std::vector &children ) const +{ + App::OriginGroup *group = static_cast ( getObject() ); + App::DocumentObject *originObj = group->Origin.getValue(); + + // Origin must be first + if (originObj) { + std::vector rv; + rv.push_back (originObj); + std::copy (children.begin(), children.end(), std::back_inserter (rv)); + return rv; + } else { // Generally shouldn't happen but must be handled in case origin is lost + return children; + } +} + + +std::vector ViewProviderOriginGroup::claimChildren () const { + return constructChildren ( ViewProviderGeoFeatureGroup::claimChildren () ); +} + +std::vector ViewProviderOriginGroup::claimChildren3D () const { + return constructChildren ( ViewProviderGeoFeatureGroup::claimChildren3D () ); +} + +void ViewProviderOriginGroup::attach(App::DocumentObject *pcObject) { + ViewProviderGeoFeatureGroup::attach ( pcObject ); + + App::Document *adoc = pcObject->getDocument (); + Gui::Document *gdoc = Gui::Application::Instance->getDocument ( adoc ) ; + + assert ( adoc ); + assert ( gdoc ); + + connectChangedObjectApp = adoc->signalChangedObject.connect ( + boost::bind ( &ViewProviderOriginGroup::slotChangedObjectApp, this, _1) ); + + connectChangedObjectGui = gdoc->signalChangedObject.connect ( + boost::bind ( &ViewProviderOriginGroup::slotChangedObjectGui, this, _1) ); +} + +void ViewProviderOriginGroup::updateData ( const App::Property* prop ) { + App::OriginGroup *group = static_cast ( getObject() ); + if ( group && prop == &group->Group ) { + updateOriginSize(); + } + + ViewProviderGeoFeatureGroup::updateData ( prop ); +} + +void ViewProviderOriginGroup::slotChangedObjectApp ( const App::DocumentObject& obj) { + App::OriginGroup *group = static_cast ( getObject() ); + if ( group && group->hasObject (&obj, /*recusive=*/ true ) ) { + updateOriginSize (); + } +} + +void ViewProviderOriginGroup::slotChangedObjectGui ( const Gui::ViewProviderDocumentObject& vp) { + if ( !vp.isDerivedFrom ( Gui::ViewProviderOrigin::getClassTypeId () ) && + !vp.isDerivedFrom ( Gui::ViewProviderOriginFeature::getClassTypeId () ) ) { + // Ignore origins to avoid infinite recursion (not likely in a well-formed focument, + // but may happen in documents designed in old versions of assembly branch ) + App::OriginGroup *group = static_cast ( getObject() ); + App::DocumentObject *obj = vp.getObject (); + + if ( group && obj && group->hasObject (obj, /*recusive=*/ true ) ) { + updateOriginSize (); + } + } +} + +void ViewProviderOriginGroup::updateOriginSize () { + App::OriginGroup* group = static_cast ( getObject() ); + + // obtain an Origin and it's ViewProvider + App::Origin* origin = 0; + Gui::ViewProviderOrigin* vpOrigin = 0; + try { + origin = group->getOrigin (); + assert (origin); + + Gui::ViewProvider *vp = Gui::Application::Instance->getViewProvider(origin); + if (!vp) { + throw Base::Exception ("No view provider linked to the Origin"); + } + assert ( vp->isDerivedFrom ( Gui::ViewProviderOrigin::getClassTypeId () ) ); + vpOrigin = static_cast ( vp ); + } catch (const Base::Exception &ex) { + Base::Console().Error ("%s\n", ex.what() ); + return; + } + + + Gui::Document* gdoc = Gui::Application::Instance->getDocument(getObject()->getDocument()); + if(!gdoc) + return; + + Gui::MDIView* view = gdoc->getViewOfViewProvider(this); + if(!view) + return; + + Gui::View3DInventorViewer* viewer = static_cast(view)->getViewer(); + SoGetBoundingBoxAction bboxAction(viewer->getSoRenderManager()->getViewportRegion()); + + // calculate the bounding box for out content + SbBox3f bbox(0,0,0, 0,0,0); + for(App::DocumentObject* obj : group->getGeoSubObjects()) { + ViewProvider *vp = Gui::Application::Instance->getViewProvider(obj); + if (!vp) { + continue; + } + + bboxAction.apply ( vp->getRoot () ); + bbox.extendBy ( bboxAction.getBoundingBox () ); + }; + + // get the bounding box values + SbVec3f max = bbox.getMax(); + SbVec3f min = bbox.getMin(); + + Base::Vector3d size; + + for (uint_fast8_t i=0; i<3; i++) { + size[i] = std::max ( fabs ( max[i] ), fabs ( min[i] ) ); + if (size[i] < 1e-7) { // TODO replace the magic values (2015-08-31, Fat-Zer) + size[i] = ViewProviderOrigin::defaultSize(); + } + } + + vpOrigin->Size.setValue ( size * 1.3 ); +} diff --git a/src/Gui/ViewProviderOriginGroup.h b/src/Gui/ViewProviderOriginGroup.h new file mode 100644 index 000000000..c381f7745 --- /dev/null +++ b/src/Gui/ViewProviderOriginGroup.h @@ -0,0 +1,62 @@ +/*************************************************************************** + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef VIEWPROVIDERORIGINGROUP_H_JIXBOPA7 +#define VIEWPROVIDERORIGINGROUP_H_JIXBOPA7 + +#include + +#include "ViewProviderGeoFeatureGroup.h" + +namespace Gui { + +class GuiExport ViewProviderOriginGroup: public ViewProviderGeoFeatureGroup +{ + PROPERTY_HEADER(Gui::ViewProviderOriginGroup); +public: + ViewProviderOriginGroup (); + virtual ~ViewProviderOriginGroup (); + + virtual std::vector claimChildren(void)const; + virtual std::vector claimChildren3D(void)const; + + virtual void attach(App::DocumentObject *pcObject); + virtual void updateData(const App::Property* prop); + + void updateOriginSize(); + +protected: + void slotChangedObjectApp ( const App::DocumentObject& obj ); + void slotChangedObjectGui ( const Gui::ViewProviderDocumentObject& obj ); + +private: + std::vector constructChildren ( + const std::vector &children ) const; + + boost::signals::connection connectChangedObjectApp; + boost::signals::connection connectChangedObjectGui; +}; + +} /* Gui */ + + +#endif /* end of include guard: VIEWPROVIDERORIGINGROUP_H_JIXBOPA7 */ diff --git a/src/Gui/ViewProviderPart.cpp b/src/Gui/ViewProviderPart.cpp new file mode 100644 index 000000000..7ca34d7a0 --- /dev/null +++ b/src/Gui/ViewProviderPart.cpp @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (c) 2006 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +#endif + +#include +#include + +#include "ActiveObjectList.h" +#include "BitmapFactory.h" +#include "Command.h" + +#include "ViewProviderPart.h" + + +using namespace Gui; + + +PROPERTY_SOURCE(Gui::ViewProviderPart, Gui::ViewProviderOriginGroup) + + +/** + * Creates the view provider for an object group. + */ +ViewProviderPart::ViewProviderPart() +{ } + +ViewProviderPart::~ViewProviderPart() +{ } + +/** + * TODO + * Whenever a property of the group gets changed then the same property of all + * associated view providers of the objects of the object group get changed as well. + */ +void ViewProviderPart::onChanged(const App::Property* prop) { + ViewProviderOriginGroup::onChanged(prop); +} + +bool ViewProviderPart::doubleClicked(void) +{ + //make the part the active one + Gui::Command::doCommand(Gui::Command::Gui, + "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", + PARTKEY, this->getObject()->getNameInDocument()); + + return true; +} + +bool ViewProviderPart::canDropObject(App::DocumentObject* obj) const { + + //it is not allowed to have any part or assembly object within a part, hence we exclude origin groups + if(obj->isDerivedFrom(App::OriginGroup::getClassTypeId())) + return false; + + return Gui::ViewProvider::canDropObject(obj); +} + + +/** + * Returns the pixmap for the list item. + */ +QIcon ViewProviderPart::getIcon() const +{ + // TODO Make a nice icon for the part (2015-09-01, Fat-Zer) + QIcon groupIcon; + groupIcon.addPixmap(QApplication::style()->standardPixmap(QStyle::SP_DirClosedIcon), + QIcon::Normal, QIcon::Off); + groupIcon.addPixmap(QApplication::style()->standardPixmap(QStyle::SP_DirOpenIcon), + QIcon::Normal, QIcon::On); + return groupIcon; +} + +// Python feature ----------------------------------------------------------------------- + +namespace Gui { +/// @cond DOXERR +PROPERTY_SOURCE_TEMPLATE(Gui::ViewProviderPartPython, Gui::ViewProviderPart) +/// @endcond + +// explicit template instantiation +template class GuiExport ViewProviderPythonFeatureT; +} diff --git a/src/Gui/ViewProviderPart.h b/src/Gui/ViewProviderPart.h new file mode 100644 index 000000000..53bf882e7 --- /dev/null +++ b/src/Gui/ViewProviderPart.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (c) 2006 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDER_ViewProviderPart_H +#define GUI_VIEWPROVIDER_ViewProviderPart_H + + +#include "ViewProviderOriginGroup.h" +#include "ViewProviderPythonFeature.h" + + +namespace Gui { + +class GuiExport ViewProviderPart : public ViewProviderOriginGroup +{ + PROPERTY_HEADER(Gui::ViewProviderPart); + +public: + /// constructor. + ViewProviderPart(); + /// destructor. + virtual ~ViewProviderPart(); + + QIcon getIcon(void) const; + + virtual bool doubleClicked(void); + virtual bool canDropObject(App::DocumentObject*) const; +protected: + /// get called by the container whenever a property has been changed + virtual void onChanged(const App::Property* prop); +}; + +typedef ViewProviderPythonFeatureT ViewProviderPartPython; + +} // namespace Gui + +#endif // GUI_VIEWPROVIDER_DOCUMENTOBJECTGROUP_H + diff --git a/src/Gui/ViewProviderPlacement.cpp b/src/Gui/ViewProviderPlacement.cpp index 2d94c730b..c272bd56b 100644 --- a/src/Gui/ViewProviderPlacement.cpp +++ b/src/Gui/ViewProviderPlacement.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2012 * + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2012 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -44,6 +44,7 @@ #include #include #include "ViewProviderPlacement.h" +#include "SoFCSelection.h" #include "Application.h" #include "Document.h" #include "View3DInventorViewer.h" @@ -61,15 +62,15 @@ using namespace Gui; PROPERTY_SOURCE(Gui::ViewProviderPlacement, Gui::ViewProviderGeometryObject) -ViewProviderPlacement::ViewProviderPlacement() +ViewProviderPlacement::ViewProviderPlacement() { - + pMat = new SoMaterial(); pMat->ref(); const float dist = 2; const float size = 6; - const float pSize = 4; + const float pSize = 4; static const SbVec3f verts[13] = { @@ -160,7 +161,7 @@ void ViewProviderPlacement::attach(App::DocumentObject* pcObject) lineSep->addChild(pMat); lineSep->addChild(pCoords); lineSep->addChild(pLines); - + addDisplayMaskMode(lineSep, "Base"); } @@ -193,7 +194,7 @@ std::string ViewProviderPlacement::getElement(const SoDetail* detail) const SoDetail* ViewProviderPlacement::getDetail(const char* subelement) const { SoLineDetail* detail = 0; - std::string subelem(subelement); + std::string subelem(subelement); int edge = -1; if(subelem == "X-Axis") edge = 0; @@ -212,7 +213,7 @@ SoDetail* ViewProviderPlacement::getDetail(const char* subelement) const return detail; } -bool ViewProviderPlacement::isSelectable(void) const +bool ViewProviderPlacement::isSelectable(void) const { return true; } diff --git a/src/Gui/ViewProviderPlacement.h b/src/Gui/ViewProviderPlacement.h index d4a44f625..a14ee6776 100644 --- a/src/Gui/ViewProviderPlacement.h +++ b/src/Gui/ViewProviderPlacement.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2012 * + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2012 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -54,7 +54,7 @@ public: std::vector getDisplayModes(void) const; void setDisplayMode(const char* ModeName); - /// indicates if the ViewProvider use the new Selection model + /// indicates if the ViewProvider use the new Selection model virtual bool useNewSelectionModel(void) const {return true;} /// indicates if the ViewProvider can be selected virtual bool isSelectable(void) const ; diff --git a/src/Gui/ViewProviderPlane.cpp b/src/Gui/ViewProviderPlane.cpp index 2363f0380..3805e4f8b 100644 --- a/src/Gui/ViewProviderPlane.cpp +++ b/src/Gui/ViewProviderPlane.cpp @@ -1,5 +1,6 @@ /*************************************************************************** - * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2012 * + * Copyright (c) Juergen Riegel (juergen.riegel@web.de) 2012 * + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -24,171 +25,58 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +# include # include +# include # include -# include -# include +# include +# include #endif -#include -#include -#include -#include "ViewProviderPlane.h" -#include "Application.h" -#include "Document.h" -#include "View3DInventorViewer.h" -#include "Inventor/SoAutoZoomTranslation.h" -#include "SoAxisCrossKit.h" -//#include +#include "ViewProviderOrigin.h" -#include -#include -#include -#include +#include "ViewProviderPlane.h" using namespace Gui; -PROPERTY_SOURCE(Gui::ViewProviderPlane, Gui::ViewProviderGeometryObject) +PROPERTY_SOURCE(Gui::ViewProviderPlane, Gui::ViewProviderOriginFeature) -ViewProviderPlane::ViewProviderPlane() -{ - - pMat = new SoMaterial(); - pMat->ref(); +ViewProviderPlane::ViewProviderPlane() +{ } - const float size = 2; +ViewProviderPlane::~ViewProviderPlane() +{ } - static const SbVec3f verts[4] = - { - SbVec3f(size,size,0), SbVec3f(size,-size,0), +void ViewProviderPlane::attach ( App::DocumentObject *obj ) { + ViewProviderOriginFeature::attach ( obj ); + static const float size = ViewProviderOrigin::defaultSize (); + + static const SbVec3f verts[4] = { + SbVec3f(size,size,0), SbVec3f(size,-size,0), SbVec3f(-size,-size,0), SbVec3f(-size,size,0), }; // indexes used to create the edges - static const int32_t lines[6] = - { - 0,1,2,3,0,-1 - }; + static const int32_t lines[6] = { 0, 1, 2, 3, 0, -1 }; - pMat->diffuseColor.setNum(1); - pMat->diffuseColor.set1Value(0, SbColor(1.0f, 1.0f, 1.0f)); + SoSeparator *sep = getOriginFeatureRoot (); - pCoords = new SoCoordinate3(); - pCoords->ref(); - pCoords->point.setNum(4); - pCoords->point.setValues(0, 4, verts); + SoCoordinate3 *pCoords = new SoCoordinate3 (); + pCoords->point.setNum (4); + pCoords->point.setValues ( 0, 4, verts ); + sep->addChild ( pCoords ); - pLines = new SoIndexedLineSet(); + SoIndexedLineSet *pLines = new SoIndexedLineSet (); pLines->ref(); pLines->coordIndex.setNum(6); pLines->coordIndex.setValues(0, 6, lines); - sPixmap = "view-measurement"; + sep->addChild ( pLines ); + + SoTranslation *textTranslation = new SoTranslation (); + textTranslation->ref (); + textTranslation->translation.setValue ( SbVec3f ( -size * 49. / 50., size * 9./10., 0 ) ); + sep->addChild ( textTranslation ); + + sep->addChild ( getLabel () ); } - -ViewProviderPlane::~ViewProviderPlane() -{ - pCoords->unref(); - pLines->unref(); - pMat->unref(); -} - -void ViewProviderPlane::onChanged(const App::Property* prop) -{ - ViewProviderGeometryObject::onChanged(prop); -} - -std::vector ViewProviderPlane::getDisplayModes(void) const -{ - // add modes - std::vector StrList; - StrList.push_back("Base"); - return StrList; -} - -void ViewProviderPlane::setDisplayMode(const char* ModeName) -{ - if (strcmp(ModeName, "Base") == 0) - setDisplayMaskMode("Base"); - ViewProviderGeometryObject::setDisplayMode(ModeName); -} - -void ViewProviderPlane::attach(App::DocumentObject* pcObject) -{ - ViewProviderGeometryObject::attach(pcObject); - - SoAnnotation *lineSep = new SoAnnotation(); - - - SoAutoZoomTranslation *zoom = new SoAutoZoomTranslation; - - SoDrawStyle* style = new SoDrawStyle(); - style->lineWidth = 1.0f; - - SoMaterialBinding* matBinding = new SoMaterialBinding; - matBinding->value = SoMaterialBinding::PER_FACE; - - lineSep->addChild(zoom); - lineSep->addChild(style); - lineSep->addChild(matBinding); - lineSep->addChild(pMat); - lineSep->addChild(pCoords); - lineSep->addChild(pLines); - - addDisplayMaskMode(lineSep, "Base"); -} - -void ViewProviderPlane::updateData(const App::Property* prop) -{ - ViewProviderGeometryObject::updateData(prop); -} - -std::string ViewProviderPlane::getElement(const SoDetail* detail) const -{ - if (detail) { - if (detail->getTypeId() == SoLineDetail::getClassTypeId()) { - const SoLineDetail* line_detail = static_cast(detail); - int edge = line_detail->getLineIndex(); - if (edge == 0) - { - return std::string("Main"); - } - } - } - - return std::string(""); -} - -SoDetail* ViewProviderPlane::getDetail(const char* subelement) const -{ - SoLineDetail* detail = 0; - std::string subelem(subelement); - int edge = -1; - - if(subelem == "Main") edge = 0; - - if(edge >= 0) { - detail = new SoLineDetail(); - detail->setPartIndex(edge); - } - - return detail; -} - -bool ViewProviderPlane::isSelectable(void) const -{ - return true; -} -// ---------------------------------------------------------------------------- - - diff --git a/src/Gui/ViewProviderPlane.h b/src/Gui/ViewProviderPlane.h index fef1575f3..378a06dc5 100644 --- a/src/Gui/ViewProviderPlane.h +++ b/src/Gui/ViewProviderPlane.h @@ -1,5 +1,6 @@ /*************************************************************************** * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2012 * + * Copyright (c) Alexander Golubev (Fat-Zer) 2015 * * * * This file is part of the FreeCAD CAx development system. * * * @@ -24,51 +25,20 @@ #ifndef GUI_ViewProviderPlane_H #define GUI_ViewProviderPlane_H -#include "ViewProviderGeometryObject.h" -#include - -class SoFontStyle; -class SoText2; -class SoBaseColor; -class SoTranslation; -class SoCoordinate3; -class SoIndexedLineSet; -class SoEventCallback; -class SoMaterial; +#include "ViewProviderOriginFeature.h" namespace Gui { - -class GuiExport ViewProviderPlane : public ViewProviderGeometryObject +class GuiExport ViewProviderPlane : public ViewProviderOriginFeature { PROPERTY_HEADER(Gui::ViewProviderPlane); - public: /// Constructor ViewProviderPlane(void); virtual ~ViewProviderPlane(); - void attach(App::DocumentObject *); - void updateData(const App::Property*); - std::vector getDisplayModes(void) const; - void setDisplayMode(const char* ModeName); - - /// indicates if the ViewProvider use the new Selection model - virtual bool useNewSelectionModel(void) const {return true;} - /// indicates if the ViewProvider can be selected - virtual bool isSelectable(void) const ; - /// return a hit element to the selection path or 0 - virtual std::string getElement(const SoDetail *) const; - virtual SoDetail* getDetail(const char*) const; - -protected: - void onChanged(const App::Property* prop); - -private: - SoCoordinate3 * pCoords; - SoMaterial * pMat; - SoIndexedLineSet * pLines; + virtual void attach ( App::DocumentObject * ); }; } //namespace Gui diff --git a/src/Gui/Workbench.cpp b/src/Gui/Workbench.cpp index b65917c26..12f73a0d2 100644 --- a/src/Gui/Workbench.cpp +++ b/src/Gui/Workbench.cpp @@ -639,6 +639,14 @@ DockWindowItems* StdWorkbench::setupDockWindows() const root->addDockWidget("Std_CombiView", Qt::LeftDockWidgetArea, false, false); root->addDockWidget("Std_ReportView", Qt::BottomDockWidgetArea, true, true); root->addDockWidget("Std_PythonView", Qt::BottomDockWidgetArea, true, true); + + //Dagview through parameter. + ParameterGrp::handle group = App::GetApplication().GetUserParameter(). + GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("DAGView"); + bool enabled = group->GetBool("Enabled", false); + if (enabled) + root->addDockWidget("Std_DAGView", Qt::RightDockWidgetArea, false, false); + return root; } diff --git a/src/Mod/Assembly/App/AppAssembly.cpp b/src/Mod/Assembly/App/AppAssembly.cpp index 724a1e17e..899a8dbc0 100644 --- a/src/Mod/Assembly/App/AppAssembly.cpp +++ b/src/Mod/Assembly/App/AppAssembly.cpp @@ -30,6 +30,13 @@ #include #include +#include "Item.h" +#include "Product.h" +#include "ProductRef.h" + +#include "Constraint.h" +#include "ConstraintGroup.h" + extern struct PyMethodDef Assembly_methods[]; @@ -39,12 +46,12 @@ PyDoc_STRVAR(module_Assembly_doc, /* Python entry */ extern "C" { -void AppAssemblyExport initAssembly() +void AssemblyExport initAssembly() { // load dependend module try { - Base::Interpreter().loadModule("Part"); - //Base::Interpreter().loadModule("Mesh"); + Base::Interpreter().runString("import Part"); + //Base::Interpreter().runString("import PartDesign"); } catch(const Base::Exception& e) { PyErr_SetString(PyExc_ImportError, e.what()); @@ -61,7 +68,14 @@ void AppAssemblyExport initAssembly() // call PyType_Ready, otherwise we run into a segmentation fault, later on. // This function is responsible for adding inherited slots from a type's base class. - //Assembly::FeatureViewPart ::init(); + // Item hirachy + Assembly::Item ::init(); + Assembly::Product ::init(); + Assembly::ProductRef ::init(); + + // constraint hirachy + Assembly::Constraint ::init(); + Assembly::ConstraintGroup ::init(); } } // extern "C" diff --git a/src/Mod/Assembly/App/AppAssemblyPy.cpp b/src/Mod/Assembly/App/AppAssemblyPy.cpp index 5d2997e5e..2a7b171c2 100644 --- a/src/Mod/Assembly/App/AppAssemblyPy.cpp +++ b/src/Mod/Assembly/App/AppAssemblyPy.cpp @@ -22,11 +22,70 @@ #include "PreCompiled.h" -#ifndef _PreComp_ -# include +#ifndef _PreComp_ +# include #endif +#include +#include + +#include + +#include +#include +#include + +#include + +#include "ViewProviderBody.h" +#include "Utils.h" + + +//static PyObject * setActiveBody(PyObject *self, PyObject *args) +//{ +// PyObject *object=0; +// if (PyArg_ParseTuple(args,"|O!",&(PartDesign::BodyPy::Type), &object)&& object) { +// PartDesign::Body* Item = static_cast(object)->getBodyPtr(); +// // Should be set! +// assert(Item); +// +// // Set old body inactive if we are activating another body in the same document +// if ((PartDesignGui::ActivePartObject != NULL) && +// (PartDesignGui::ActivePartObject->getDocument() == Item->getDocument())) +// PartDesignGui::ActivePartObject->IsActive.setValue(false); +// PartDesignGui::ActivePartObject = Item; +// PartDesignGui::ActiveAppDoc = Item->getDocument(); +// PartDesignGui::ActiveGuiDoc = Gui::Application::Instance->getDocument(PartDesignGui::ActiveAppDoc); +// PartDesignGui::ActiveVp = dynamic_cast (PartDesignGui::ActiveGuiDoc->getViewProvider(Item)); +// PartDesignGui::ActiveVp->show(); +// Item->IsActive.setValue(true); +// } else { +// // This handles the case of deactivating the workbench +// PartDesignGui::ActivePartObject=0; +// PartDesignGui::ActiveGuiDoc =0; +// PartDesignGui::ActiveAppDoc =0; +// PartDesignGui::ActiveVp =0; +// } +// +// Py_Return; +//} +// +//static PyObject * getActiveBody(PyObject *, PyObject *) +//{ +// if (PartDesignGui::ActivePartObject == NULL) { +// return Py::_None(); +// } +// +// return PartDesignGui::ActivePartObject->getPyObject(); +//} + /* registration table */ struct PyMethodDef Assembly_methods[] = { + //{"setActiveBody" ,setActiveBody ,METH_VARARGS, + // "setActiveBody(BodyObject) -- Set the PartBody object in work."}, + + //{"getActiveBody" ,getActiveBody ,METH_NOARGS, + // "getActiveBody() -- Get the PartBody object in work."}, + {NULL, NULL} /* end of table marker */ }; diff --git a/src/Mod/Assembly/App/CMakeLists.txt b/src/Mod/Assembly/App/CMakeLists.txt index 50537fd16..9d7eaf1bb 100644 --- a/src/Mod/Assembly/App/CMakeLists.txt +++ b/src/Mod/Assembly/App/CMakeLists.txt @@ -1,34 +1,114 @@ +if(MSVC) + add_definitions(-DHAVE_ACOSH -DHAVE_ASINH -DHAVE_ATANH) +else(MSVC) + add_definitions(-DHAVE_LIMITS_H -DHAVE_CONFIG_H) +endif(MSVC) include_directories( ${CMAKE_SOURCE_DIR}/src + ${CMAKE_BINARY_DIR}/src + ${CMAKE_SOURCE_DIR}/src/Mod/Assembly/App + ${CMAKE_CURRENT_BINARY_DIR} ${Boost_INCLUDE_DIRS} ${OCC_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR} ${XercesC_INCLUDE_DIRS} - # ${ODE_INCLUDE_DIRS} + #${ODE_INCLUDE_DIRS} + ${EIGEN3_INCLUDE_DIR} + ) +link_directories(${OCC_LIBRARY_DIR}) + set(Assembly_LIBS -# ${ODE_LIBRARIES} + #${ODE_LIBRARIES} + ${OCC_LIBRARIES} + ${Boost_LIBRARIES} + ${Boost_LOG_LIBRARY_RELEASE} + Part FreeCADApp ) -SET(Assembly_SRCS +generate_from_xml(ItemPy) +generate_from_xml(ProductRefPy) +#generate_from_xml(PartRefPy) +generate_from_xml(ConstraintPy) +generate_from_xml(ConstraintGroupPy) + +SET(Features_SRCS + Item.cpp + Item.h + #PartRef.cpp + #PartRef.h + Product.cpp + Product.h + ProductRef.cpp + ProductRef.h + Constraint.cpp + Constraint.h + ConstraintGroup.cpp + ConstraintGroup.h +) +SOURCE_GROUP("Features" FILES ${Features_SRCS}) + +SET(Module_SRCS AppAssembly.cpp AppAssemblyPy.cpp PreCompiled.cpp PreCompiled.h ) +SOURCE_GROUP("Module" FILES ${Module_SRCS}) + +#externalisation is not possible for msvc as a stupid bug prevents the function definition resolving +if(MSVC) + set(Solver_SRC ) +else(MSVC) + set(Solver_SRC Solver/solver_3d_ext1.cpp + Solver/solver_3d_ext2.cpp + Solver/solver_3d_ext3.cpp + ) + + if(FREECAD_ASSEMBLY_DEBUG_FACILITIES) + set(Solver_SRC ${Solver_SRC} + Solver/solver_state_ext1.cpp + Solver/solver_state_ext2.cpp + ) + endif(FREECAD_ASSEMBLY_DEBUG_FACILITIES) +endif(MSVC) + +SOURCE_GROUP("Solver" FILES ${Solver_SRC}) + +SET(Python_SRCS + ItemPy.xml + ItemPyImp.cpp + ProductRefPy.xml + ProductRefPyImp.cpp + #PartRefPy.xml + #PartRefPyImp.cpp + ConstraintPy.xml + ConstraintPyImp.cpp + ConstraintGroupPy.xml + ConstraintGroupPyImp.cpp +) +SOURCE_GROUP("Python" FILES ${Python_SRCS}) + +SET(Assembly_SRCS + ${Features_SRCS} + ${Python_SRCS} + ${Module_SRCS} + ${Solver_SRC} +) add_library(Assembly SHARED ${Assembly_SRCS}) -target_link_libraries(Assembly ${Assembly_LIBS}) +target_link_libraries(Assembly ${Assembly_LIBS} ${log_LIB}) fc_target_copy_resource(Assembly ${CMAKE_SOURCE_DIR}/src/Mod/Assembly ${CMAKE_BINARY_DIR}/Mod/Assembly - Init.py) + Init.py + AssemblyLib.py) SET_BIN_DIR(Assembly Assembly /Mod/Assembly) SET_PYTHON_PREFIX_SUFFIX(Assembly) diff --git a/src/Mod/Assembly/App/Constraint.cpp b/src/Mod/Assembly/App/Constraint.cpp new file mode 100644 index 000000000..b851c105f --- /dev/null +++ b/src/Mod/Assembly/App/Constraint.cpp @@ -0,0 +1,123 @@ +/*************************************************************************** + * Copyright (c) 2012 Juergen Riegel * + * Copyright (c) 2013 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development m_solvertem. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "Constraint.h" +#include "ConstraintPy.h" +#include "Item.h" +#include "Product.h" + + +using namespace Assembly; + +namespace Assembly { + +struct ConstraintInitException : std::exception { + const char* what() const throw() { + return "Constraint cout not be initialised: unsoported geometry"; + } +}; +struct ConstraintPartException : std::exception { + const char* what() const throw() { + return "Constraint cout not be initialised: parts are invalid"; + } +}; +struct ConstraintLinkException : std::exception { + const char* what() const throw() { + return "Constraint cout not be initialised: unsoported link type"; + } +}; + +PROPERTY_SOURCE(Assembly::Constraint, App::DocumentObject) + +const char* Constraint::OrientationEnums[] = {"Parallel","Equal","Opposite","Perpendicular",NULL}; +const char* Constraint::TypeEnums[] = {"Fix","Distance","Orientation","Angle","Align","Coincident","None",NULL}; +const char* Constraint::SolutionSpaceEnums[] = {"Bidirectional","PositivDirectional","NegativeDirectional",NULL}; + +Constraint::Constraint() +{ + ADD_PROPERTY(First, (0)); + ADD_PROPERTY(Second,(0)); + ADD_PROPERTY(Value,(0)); + ADD_PROPERTY(Orientation, (long(0))); + Orientation.setEnums(OrientationEnums); + ADD_PROPERTY(Type, (long(6))); + Type.setEnums(TypeEnums); + ADD_PROPERTY(SolutionSpace, (long(0))); + SolutionSpace.setEnums(SolutionSpaceEnums); +} + +short Constraint::mustExecute() const +{ + //if (Sketch.isTouched() || + // Length.isTouched()) + // return 1; + return 0; +} + +App::DocumentObjectExecReturn* Constraint::execute(void) +{ + return App::DocumentObject::StdReturn; +} + + +PyObject* Constraint::getPyObject(void) +{ + if(PythonObject.is(Py::_None())) { + // ref counter is set to 1 + PythonObject = Py::Object(new ConstraintPy(this),true); + } + + return Py::new_reference_to(PythonObject); +} + + +} + + + diff --git a/src/Mod/Assembly/App/Constraint.h b/src/Mod/Assembly/App/Constraint.h new file mode 100644 index 000000000..b40f9f886 --- /dev/null +++ b/src/Mod/Assembly/App/Constraint.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (c) 2012 Juergen Riegel * + * Copyright (c) 2013 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef Assembly_Constraint_H +#define Assembly_Constraint_H + +#include +#include + +#include + +#include "Solver/Solver.h" +#include "Product.h" + + +namespace Assembly +{ + +class AssemblyExport Constraint : public App::DocumentObject +{ + PROPERTY_HEADER(Assembly::Constraint); + +public: + Constraint(); + + App::PropertyLinkSub First; + App::PropertyLinkSub Second; + App::PropertyFloat Value; + App::PropertyEnumeration Orientation; + App::PropertyEnumeration SolutionSpace; + App::PropertyEnumeration Type; + + /** @name methods override feature */ + //@{ + /// recalculate the feature + App::DocumentObjectExecReturn *execute(void); + short mustExecute() const; + /// returns the type name of the view provider + const char* getViewProviderName(void) const { + return "AssemblyGui::ViewProviderConstraint"; + } + PyObject *getPyObject(void); + +private: + static const char* OrientationEnums[]; + static const char* TypeEnums[]; + static const char* SolutionSpaceEnums[]; +}; + +} //namespace Assembly + + +#endif // Assembly_Constraint_H diff --git a/src/Mod/Assembly/App/ConstraintGroup.cpp b/src/Mod/Assembly/App/ConstraintGroup.cpp new file mode 100644 index 000000000..fe9894a53 --- /dev/null +++ b/src/Mod/Assembly/App/ConstraintGroup.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (c) 2010 Juergen Riegel * + * Copyright (c) 2013 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +#endif + +#include +#include + +#include "ConstraintGroupPy.h" +#include "ConstraintGroup.h" +#include "Product.h" + + +using namespace Assembly; + +namespace Assembly { + + +PROPERTY_SOURCE(Assembly::ConstraintGroup, App::DocumentObject) + +ConstraintGroup::ConstraintGroup() +{ + ADD_PROPERTY(Constraints,(0)); +} + +PyObject *ConstraintGroup::getPyObject(void) +{ + if (PythonObject.is(Py::_None())){ + // ref counter is set to 1 + PythonObject = Py::Object(new ConstraintGroupPy(this),true); + } + return Py::new_reference_to(PythonObject); +} + + +short ConstraintGroup::mustExecute() const +{ + //if (Sketch.isTouched() || + // Length.isTouched()) + // return 1; + return 0; +} + +App::DocumentObjectExecReturn *ConstraintGroup::execute(void) +{ + + touch(); + return App::DocumentObject::StdReturn; +} + + + +} diff --git a/src/Mod/Assembly/App/ConstraintGroup.h b/src/Mod/Assembly/App/ConstraintGroup.h new file mode 100644 index 000000000..1fa281cd7 --- /dev/null +++ b/src/Mod/Assembly/App/ConstraintGroup.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (c) 2010 Juergen Riegel * + * Copyright (c) 2013 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef Assembly_ConstraintGroup_H +#define Assembly_ConstraintGroup_H + +#include +#include +#include + +#include "Constraint.h" +#include "Solver/Solver.h" + +namespace Assembly +{ + +class AssemblyExport ConstraintGroup : public App::DocumentObject +{ + PROPERTY_HEADER(Assembly::ConstraintGroup); + +public: + ConstraintGroup(); + + PyObject *getPyObject(void); + + App::PropertyLinkList Constraints; + + /** @name methods override feature */ + //@{ + /// recalculate the feature + App::DocumentObjectExecReturn *execute(void); + short mustExecute() const; + /// returns the type name of the view provider + const char* getViewProviderName(void) const { + return "AssemblyGui::ViewProviderConstraintGroup"; + } + //@} + +}; + +} //namespace Assembly + + +#endif // Assembly_ConstraintGroup_H diff --git a/src/Mod/Assembly/App/ConstraintGroupPy.xml b/src/Mod/Assembly/App/ConstraintGroupPy.xml new file mode 100644 index 000000000..fbc07d2f8 --- /dev/null +++ b/src/Mod/Assembly/App/ConstraintGroupPy.xml @@ -0,0 +1,19 @@ + + + + + + Base class of all objects in Assembly + + + + + diff --git a/src/Mod/Assembly/App/ConstraintGroupPyImp.cpp b/src/Mod/Assembly/App/ConstraintGroupPyImp.cpp new file mode 100644 index 000000000..d315c9b64 --- /dev/null +++ b/src/Mod/Assembly/App/ConstraintGroupPyImp.cpp @@ -0,0 +1,29 @@ + +#include "PreCompiled.h" + +#include "Mod/Assembly/App/ConstraintGroup.h" +#include "Mod/Assembly/App/ConstraintPy.h" + +// inclusion of the generated files (generated out of ConstraintGroupPy.xml) +#include "ConstraintGroupPy.h" +#include "ConstraintGroupPy.cpp" + +using namespace Assembly; + +// returns a string which represents the object e.g. when printed in python +std::string ConstraintGroupPy::representation(void) const +{ + return std::string(""); +} + +PyObject *ConstraintGroupPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int ConstraintGroupPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} + + diff --git a/src/Mod/Assembly/App/ConstraintPy.xml b/src/Mod/Assembly/App/ConstraintPy.xml new file mode 100644 index 000000000..499502761 --- /dev/null +++ b/src/Mod/Assembly/App/ConstraintPy.xml @@ -0,0 +1,17 @@ + + + + + + Base class of all objects in Assembly + + + diff --git a/src/Mod/Assembly/App/ConstraintPyImp.cpp b/src/Mod/Assembly/App/ConstraintPyImp.cpp new file mode 100644 index 000000000..7d684c909 --- /dev/null +++ b/src/Mod/Assembly/App/ConstraintPyImp.cpp @@ -0,0 +1,29 @@ + +#include "PreCompiled.h" + +#include "Mod/Assembly/App/Constraint.h" + +// inclusion of the generated files (generated out of ItemAssemblyPy.xml) +#include "ConstraintPy.h" +#include "ConstraintPy.cpp" + +using namespace Assembly; + +// returns a string which represents the object e.g. when printed in python +std::string ConstraintPy::representation(void) const +{ + return std::string(""); +} + + +PyObject *ConstraintPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int ConstraintPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} + + diff --git a/src/Mod/Assembly/App/Item.cpp b/src/Mod/Assembly/App/Item.cpp new file mode 100644 index 000000000..b9b743a6e --- /dev/null +++ b/src/Mod/Assembly/App/Item.cpp @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (c) 2010 Juergen Riegel * + * Copyright (c) 2013 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +#endif + +#include +#include +#include + +#include "Item.h" +#include "ItemPy.h" +#include + +using namespace Assembly; + +namespace Assembly { + + +PROPERTY_SOURCE_ABSTRACT(Assembly::Item, App::GeoFeature) + +Item::Item() +{ + ADD_PROPERTY_TYPE(Meta, (), 0, App::Prop_None, "Map with additional meta information"); + +} + +short Item::mustExecute() const +{ + //if (Sketch.isTouched() || + // Length.isTouched()) + // return 1; + return 0; +} + +App::DocumentObjectExecReturn *Item::execute(void) +{ + + Base::Console().Message("Recalculate Assembly::Item\n"); + return App::DocumentObject::StdReturn; +} + +PyObject *Item::getPyObject(void) +{ + if (PythonObject.is(Py::_None())){ + // ref counter is set to 1 + PythonObject = Py::Object(new ItemPy(this),true); + } + return Py::new_reference_to(PythonObject); +} + +} \ No newline at end of file diff --git a/src/Mod/Assembly/App/Item.h b/src/Mod/Assembly/App/Item.h new file mode 100644 index 000000000..7a9fe978a --- /dev/null +++ b/src/Mod/Assembly/App/Item.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (c) 2010 Juergen Riegel * + * Copyright (c) 2013 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef Assembly_Item_H +#define Assembly_Item_H + +#include +#include +#include + +namespace Assembly +{ + +/// Base class of all Assembly objects +class AssemblyExport Item : public App::GeoFeature +{ + PROPERTY_HEADER(Assembly::Item); + +public: + Item(); + ~Item() {}; + + /// Meta descriptons + App::PropertyMap Meta; + + /** @name methods override feature */ + //@{ + /// recalculate the feature + App::DocumentObjectExecReturn *execute(void); + short mustExecute() const; + /// returns the type name of the view provider + const char* getViewProviderName(void) const { + return "AssemblyGui::ViewProviderItem"; + } + //@} + + PyObject *getPyObject(void); + +}; + +} //namespace Assembly + + +#endif // ASSEMBLY_Item_H diff --git a/src/Mod/Assembly/App/ItemPy.xml b/src/Mod/Assembly/App/ItemPy.xml new file mode 100644 index 000000000..d9bca2eea --- /dev/null +++ b/src/Mod/Assembly/App/ItemPy.xml @@ -0,0 +1,17 @@ + + + + + + Base class of all objects in Assembly + + + diff --git a/src/Mod/Assembly/App/ItemPyImp.cpp b/src/Mod/Assembly/App/ItemPyImp.cpp new file mode 100644 index 000000000..b2f591856 --- /dev/null +++ b/src/Mod/Assembly/App/ItemPyImp.cpp @@ -0,0 +1,34 @@ + +#include "PreCompiled.h" + +#include "Mod/Assembly/App/Item.h" + +// inclusion of the generated files (generated out of ItemPy.xml) +#include "ItemPy.h" +#include "ItemPy.cpp" + +using namespace Assembly; + +// returns a string which represents the object e.g. when printed in python +std::string ItemPy::representation(void) const +{ + return std::string(""); +} + + + + + + + +PyObject *ItemPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int ItemPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} + + diff --git a/src/Mod/Assembly/App/PartRef.cpp b/src/Mod/Assembly/App/PartRef.cpp new file mode 100644 index 000000000..c82d0962c --- /dev/null +++ b/src/Mod/Assembly/App/PartRef.cpp @@ -0,0 +1,233 @@ +/*************************************************************************** + * Copyright (c) 2012 Juergen Riegel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +#endif + +#include +#include + +#include "PartRef.h" +#include "Product.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace Assembly; + +namespace Assembly { + +struct AssemblyItemException : std::exception { + const char* what() const throw() { return "Assembly items are in wrong structure";} +}; + + +PROPERTY_SOURCE(Assembly::PartRef, App::GeoFeature) + +PartRef::PartRef() { + ADD_PROPERTY(Model, (0)); + ADD_PROPERTY(Annotation,(0)); +} + +short PartRef::mustExecute() const { + //if (Sketch.isTouched() || + // Length.isTouched()) + // return 1; + return 0; +} + +App::DocumentObjectExecReturn* PartRef::execute(void) { + + this->touch(); + return App::DocumentObject::StdReturn; +} + +TopoDS_Shape PartRef::getShape(void) const { + App::DocumentObject* obj = Model.getValue(); + + if(obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + return static_cast(obj)->Shape.getValue(); + } + + return TopoDS_Shape(); +} + +PyObject* PartRef::getPyObject(void) { + if(PythonObject.is(Py::_None())) { + // ref counter is set to 1 + PythonObject = Py::Object(new PartRefPy(this),true); + } + return Py::new_reference_to(PythonObject); +} + +bool PartRef::holdsObject(App::DocumentObject* obj) const { + + //get the body object and the relevant model list + Part::BodyBase* base = static_cast(Model.getValue()); + const std::vector& vector = base->Model.getValues(); + + //check if it holds the relevant document object + return std::find(vector.begin(), vector.end(), obj)!=vector.end(); +} + +void PartRef::setCalculatedPlacement(boost::shared_ptr< Part3D > part) { + + //part is the same as m_part, so it doasn't matter which one we use + Base::Placement p = dcm::get(part); + + Product* ass = getParentAssembly(); + if(!ass) + throw AssemblyItemException(); + + if(ass->Rigid.getValue()) + Placement.setValue(p); + else + Placement.setValue(ass->m_downstream_placement.inverse()*p); +} + +Product* PartRef::getParentAssembly() { + + typedef std::vector::const_iterator iter; + + const std::vector& vector = getInList(); + for(iter it=vector.begin(); it != vector.end(); it++) { + + if((*it)->getTypeId() == Assembly::Product::getClassTypeId()) + return static_cast(*it); + }; + + return (Product*)NULL; +} + +void PartRef::ensureInitialisation() { + + Product* ass = getParentAssembly(); + if(!ass) + throw AssemblyItemException(); + + boost::shared_ptr solver = ass->m_solver; + if(!solver) + throw AssemblyItemException(); + + if(!solver->hasPart(Uid.getValueStr())) { + + //if the assembly is not rigid it was not added to the solver, so we need to incorporate its placement + if(ass->Rigid.getValue()) { + m_part = solver->createPart(Placement.getValue(), Uid.getValueStr()); + } + else { + m_part = solver->createPart(ass->m_downstream_placement*Placement.getValue(), Uid.getValueStr()); + } + m_part->connectSignal(boost::bind(&PartRef::setCalculatedPlacement, this, _1)); + }; +} + + +boost::shared_ptr< Geometry3D > PartRef::getGeometry3D(const char* Type) { + + //check if the item is initialized + if(!m_part) + return boost::shared_ptr< Geometry3D >(); + + boost::shared_ptr geometry; + if(m_part->hasGeometry3D(Type)) { + return m_part->getGeometry3D(Type); + } + else { + Part::TopoShape ts; + App::DocumentObject* obj = Model.getValue(); + + if(obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + ts = static_cast(obj)->Shape.getShape(); + } + else + return boost::shared_ptr< Geometry3D >(); + + TopoDS_Shape s = ts.getSubShape(Type); + if(s.ShapeType() == TopAbs_FACE) { + TopoDS_Face face = TopoDS::Face(s); + BRepAdaptor_Surface surface(face); + switch(surface.GetType()) { + case GeomAbs_Plane: { + gp_Pln plane = surface.Plane(); + if(face.Orientation()==TopAbs_REVERSED) { + gp_Dir dir = plane.Axis().Direction(); + plane = gp_Pln(plane.Location(), dir.Reversed()); + } + geometry = m_part->addGeometry3D(plane, Type, dcm::Local); + break; + } + case GeomAbs_Cylinder: { + gp_Cylinder cyl = surface.Cylinder(); + geometry = m_part->addGeometry3D(cyl, Type, dcm::Local); + break; + } + default: + Base::Console().Message("Unsuported Surface Geometrie Type at selection\n"); + return boost::shared_ptr< Geometry3D >(); + } + + } + else + if(s.ShapeType() == TopAbs_EDGE) { + TopoDS_Edge edge = TopoDS::Edge(s); + BRepAdaptor_Curve curve(edge); + switch(curve.GetType()) { + case GeomAbs_Line: { + gp_Lin line = curve.Line(); + geometry = m_part->addGeometry3D(line, Type, dcm::Local); + break; + } + default: + Base::Console().Message("Unsuported Curve Geometrie Type at selection \n"); + return boost::shared_ptr< Geometry3D >(); + } + + } + else + if(s.ShapeType() == TopAbs_VERTEX) { + TopoDS_Vertex v1 = TopoDS::Vertex(s); + gp_Pnt point = BRep_Tool::Pnt(v1); + geometry = m_part->addGeometry3D(point, Type, dcm::Local); + + } + else { + Base::Console().Message("Unsuported Topologie Type at selection\n"); + return boost::shared_ptr< Geometry3D >(); + } + }; + + return geometry; +} + +} diff --git a/src/Mod/Assembly/App/PartRef.h b/src/Mod/Assembly/App/PartRef.h new file mode 100644 index 000000000..ff269f2ed --- /dev/null +++ b/src/Mod/Assembly/App/PartRef.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (c) 2012 Juergen Riegel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef Assembly_ItemPart_H +#define Assembly_ItemPart_H + +#include +#include + +#include "Solver/Solver.h" + + +namespace Assembly +{ + +class Product; + +class AssemblyExport PartRef : public App::GeoFeature +{ + PROPERTY_HEADER(Assembly::PartRef); + +public: + PartRef(); + + App::PropertyLink Item; + //App::PropertyLinkList Annotation; + + /** @name methods override feature */ + //@{ + /// recalculate the feature + App::DocumentObjectExecReturn *execute(void); + short mustExecute() const; + // returns the type name of the view provider + const char* getViewProviderName(void) const { + return "AssemblyGui::ViewProviderItemPart"; + } + PyObject *getPyObject(void); + //@} + + //virtual TopoDS_Shape getShape(void) const; + + bool holdsObject(App::DocumentObject* obj) const; + Product* getParentAssembly(); + void ensureInitialisation(); + + boost::shared_ptr m_part; + virtual boost::shared_ptr getGeometry3D(const char* Type ); + void setCalculatedPlacement( boost::shared_ptr part ); +}; + +} //namespace Assembly + + +#endif // Assembly_ItemPart_H diff --git a/src/Mod/Assembly/App/PartRefPy.xml b/src/Mod/Assembly/App/PartRefPy.xml new file mode 100644 index 000000000..7b0312580 --- /dev/null +++ b/src/Mod/Assembly/App/PartRefPy.xml @@ -0,0 +1,17 @@ + + + + + + Base class of all objects in Assembly + + + diff --git a/src/Mod/Assembly/App/PartRefPyImp.cpp b/src/Mod/Assembly/App/PartRefPyImp.cpp new file mode 100644 index 000000000..b2e57bb5b --- /dev/null +++ b/src/Mod/Assembly/App/PartRefPyImp.cpp @@ -0,0 +1,34 @@ + +#include "PreCompiled.h" + +#include "Mod/Assembly/App/PartRef.h" + +// inclusion of the generated files (generated out of PartRefPy.xml) +#include "PartRefPy.h" +#include "PartRefPy.cpp" + +using namespace Assembly; + +// returns a string which represents the object e.g. when printed in python +std::string PartRefPy::representation(void) const +{ + return std::string(""); +} + + + + + + + +PyObject *PartRefPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int PartRefPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} + + diff --git a/src/Mod/Assembly/App/PreCompiled.h b/src/Mod/Assembly/App/PreCompiled.h index ef82449af..8dfc4eb52 100644 --- a/src/Mod/Assembly/App/PreCompiled.h +++ b/src/Mod/Assembly/App/PreCompiled.h @@ -28,11 +28,11 @@ // Exporting of App classes #ifdef FC_OS_WIN32 -# define AppAssemblyExport __declspec(dllexport) +# define AssemblyExport __declspec(dllexport) # define PartExport __declspec(dllimport) # define MeshExport __declspec(dllimport) #else // for Linux -# define AppAssemblyExport +# define AssemblyExport # define PartExport # define MeshExport #endif diff --git a/src/Mod/Assembly/App/Product.cpp b/src/Mod/Assembly/App/Product.cpp new file mode 100644 index 000000000..7702f17ca --- /dev/null +++ b/src/Mod/Assembly/App/Product.cpp @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (c) 2012 Juergen Riegel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +# include +#include +#endif + +#include +#include +#include + +#include "Product.h" +#include "ConstraintGroup.h" + + +using namespace Assembly; + +namespace Assembly { + + +PROPERTY_SOURCE(Assembly::Product, Assembly::Item) + +Product::Product() { + ADD_PROPERTY(Items,(0)); + ADD_PROPERTY_TYPE(Material,(),0,App::Prop_None,"Map with material properties"); + // create the uuid for the document + Base::Uuid id; + ADD_PROPERTY_TYPE(Id,(""),0,App::Prop_None,"ID (Part-Number) of the Item"); + ADD_PROPERTY_TYPE(Uid,(id),0,App::Prop_None,"UUID of the Item"); + + // license stuff + ADD_PROPERTY_TYPE(License,("CC BY 3.0"),0,App::Prop_None,"License string of the Item"); + ADD_PROPERTY_TYPE(LicenseURL,("http://creativecommons.org/licenses/by/3.0/"),0,App::Prop_None,"URL to the license text/contract"); + // color and apperance + ADD_PROPERTY(Color,(1.0,1.0,1.0,1.0)); // set transparent -> not used + ADD_PROPERTY(Visibility,(true)); + +} + +short Product::mustExecute() const { + return 0; +} + +App::DocumentObjectExecReturn* Product::execute(void) { + + Base::Console().Message("Execute\n"); + + return App::DocumentObject::StdReturn; +} + + +//PyObject* Product::getPyObject(void) { +// if(PythonObject.is(Py::_None())) { +// // ref counter is set to 1 +// PythonObject = Py::Object(new ProductPy(this),true); +// } +// +// return Py::new_reference_to(PythonObject); +//} + + + +} //assembly + + + diff --git a/src/Mod/Assembly/App/Product.h b/src/Mod/Assembly/App/Product.h new file mode 100644 index 000000000..cee0291eb --- /dev/null +++ b/src/Mod/Assembly/App/Product.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright (c) 2012 Juergen Riegel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef ItemAssembly_ItemAssembly_H +#define ItemAssembly_ItemAssembly_H + +#include + +#include "Item.h" +#include "Solver/Solver.h" + +namespace Assembly +{ + + +class AssemblyExport Product : public Assembly::Item +{ + PROPERTY_HEADER(Assembly::Product); + +public: + Product(); + + /// Items of the Product + App::PropertyLinkList Items; + + /** @name base properties of all Assembly Items + * This properties corospond mostly to the meta information + * in the App::Document class + */ + //@{ + /// Id e.g. Part number + App::PropertyString Id; + /// unique identifier of the Item + App::PropertyUUID Uid; + /// material descriptons + App::PropertyMap Material; + + /** License string + * Holds the short license string for the Item, e.g. CC-BY + * for the Creative Commons license suit. + */ + App::PropertyString License; + /// License descripton/contract URL + App::PropertyString LicenseURL; + //@} + + /** @name Visual properties */ + //@{ + /** Base color of the Item + If the transparency value is 1.0 + the color or the next hirachy is used + */ + App::PropertyColor Color; + /// Visibility + App::PropertyBool Visibility; + //@} + + + /** @name methods override feature */ + //@{ + /// recalculate the feature + App::DocumentObjectExecReturn *execute(void); + short mustExecute() const; + /// returns the type name of the view provider + const char* getViewProviderName(void) const { + return "AssemblyGui::ViewProviderProduct"; + } + //PyObject *getPyObject(void); + //@} + +}; + +} //namespace Assembly + + +#endif // Assembly_ItemAssembly_H diff --git a/src/Mod/Assembly/App/ProductRef.cpp b/src/Mod/Assembly/App/ProductRef.cpp new file mode 100644 index 000000000..e4b7b85a9 --- /dev/null +++ b/src/Mod/Assembly/App/ProductRef.cpp @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright (c) 2012 Juergen Riegel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#ifndef _PreComp_ +# include +# include +#include +#endif + +#include +#include +#include + +#include "ProductRef.h" +#include "ConstraintGroup.h" +#include "ProductRefPy.h" + +using namespace Assembly; + +namespace Assembly { + + +PROPERTY_SOURCE(Assembly::ProductRef, Assembly::Item) + +ProductRef::ProductRef() { + ADD_PROPERTY(Item,(0)); +} + +short ProductRef::mustExecute() const { + return 0; +} + +App::DocumentObjectExecReturn* ProductRef::execute(void) +{ + return App::DocumentObject::StdReturn; +} + +PyObject* ProductRef::getPyObject(void) { + if(PythonObject.is(Py::_None())) { + // ref counter is set to 1 + PythonObject = Py::Object(new ProductRefPy(this),true); + } + + return Py::new_reference_to(PythonObject); +} + + +} //assembly + + + diff --git a/src/Mod/Assembly/App/ProductRef.h b/src/Mod/Assembly/App/ProductRef.h new file mode 100644 index 000000000..10665bcd9 --- /dev/null +++ b/src/Mod/Assembly/App/ProductRef.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (c) 2012 Juergen Riegel * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef ProductRef_ProductRef_H +#define ProductRef_ProductRef_H + +#include + +#include "Item.h" +#include "Solver/Solver.h" + +namespace Assembly +{ + + + +class AssemblyExport ProductRef : public Assembly::Item +{ + PROPERTY_HEADER(Assembly::ProductRef); + +public: + ProductRef(); + + /// The one and only GeomtricObject referenced + App::PropertyLink Item; + + /** @name methods override feature */ + //@{ + /// recalculate the feature + App::DocumentObjectExecReturn *execute(void); + short mustExecute() const; + /// returns the type name of the view provider + const char* getViewProviderName(void) const { + return "AssemblyGui::ViewProviderProductRef"; + } + PyObject *getPyObject(void); + //@} + +}; + +} //namespace Assembly + + +#endif // Assembly_ProductRef_H diff --git a/src/Mod/Assembly/App/ProductRefPy.xml b/src/Mod/Assembly/App/ProductRefPy.xml new file mode 100644 index 000000000..ba3bb3d8f --- /dev/null +++ b/src/Mod/Assembly/App/ProductRefPy.xml @@ -0,0 +1,17 @@ + + + + + + Base class of all objects in Assembly + + + diff --git a/src/Mod/Assembly/App/ProductRefPyImp.cpp b/src/Mod/Assembly/App/ProductRefPyImp.cpp new file mode 100644 index 000000000..a124d7ef2 --- /dev/null +++ b/src/Mod/Assembly/App/ProductRefPyImp.cpp @@ -0,0 +1,27 @@ + +#include "PreCompiled.h" + +#include "Mod/Assembly/App/ProductRef.h" + +// inclusion of the generated files (generated out of ProductRefPy.xml) +#include "ProductRefPy.h" +#include "ProductRefPy.cpp" + +using namespace Assembly; + +// returns a string which represents the object e.g. when printed in python +std::string ProductRefPy::representation(void) const +{ + return std::string(""); +} + + +PyObject *ProductRefPy::getCustomAttributes(const char* /*attr*/) const +{ + return 0; +} + +int ProductRefPy::setCustomAttributes(const char* /*attr*/, PyObject* /*obj*/) +{ + return 0; +} diff --git a/src/Mod/Assembly/App/Solver/Solver.h b/src/Mod/Assembly/App/Solver/Solver.h new file mode 100644 index 000000000..1005601f5 --- /dev/null +++ b/src/Mod/Assembly/App/Solver/Solver.h @@ -0,0 +1,414 @@ +/*************************************************************************** + * Copyright (c) 2013 Stefan Tröger * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#ifndef SOLVER_H +#define SOLVER_H + +#include "PreCompiled.h" + +#include "opendcm/core.hpp" + +#ifdef ASSEMBLY_DEBUG_FACILITIES +#include "opendcm/modulestate.hpp" +#endif +#include "opendcm/module3d.hpp" +#include "opendcm/modulepart.hpp" + +#include +#include + +#include +#include +#include +#include + +struct gp_pnt_accessor { + + template + Scalar get(T& t) { + switch(ID) { + case 0: + return t.X(); + + case 1: + return t.Y(); + + case 2: + return t.Z(); + + default: + return 0; + }; + }; + template + void set(Scalar value, T& t) { + switch(ID) { + case 0: + t.SetX(value); + break; + + case 1: + t.SetY(value); + break; + + case 2: + t.SetZ(value); + break; + }; + }; + template + void finalize(T& t) {}; +}; + +struct gp_lin_accessor { + + gp_Pnt pnt; + double dx,dy,dz; + + template + Scalar get(T& t) { + switch(ID) { + case 0: + return t.Location().X(); + + case 1: + return t.Location().Y(); + + case 2: + return t.Location().Z(); + + case 3: + return t.Direction().X(); + + case 4: + return t.Direction().Y(); + + case 5: + return t.Direction().Z(); + + default: + return 0; + }; + }; + template + void set(Scalar value, T& t) { + + switch(ID) { + case 0: + pnt.SetX(value); + break; + + case 1: + pnt.SetY(value); + break; + + case 2: + pnt.SetZ(value); + break; + + case 3: + dx=(value); + break; + + case 4: + dy=(value); + break; + + case 5: + dz=(value); + break; + }; + }; + template + void finalize(T& t) { + t.SetLocation(pnt); + t.SetDirection(gp_Dir(dx,dy,dz)); + }; +}; + +struct gp_pln_accessor { + + gp_Pnt pnt; + double dx,dy,dz; + + template + Scalar get(T& t) { + switch(ID) { + case 0: + return t.Axis().Location().X(); + + case 1: + return t.Axis().Location().Y(); + + case 2: + return t.Axis().Location().Z(); + + case 3: + return t.Axis().Direction().X(); + + case 4: + return t.Axis().Direction().Y(); + + case 5: + return t.Axis().Direction().Z(); + + default: + return 0; + }; + }; + template + void set(Scalar value, T& t) { + switch(ID) { + case 0: + pnt.SetX(value); + break; + + case 1: + pnt.SetY(value); + break; + + case 2: + pnt.SetZ(value); + break; + + case 3: + dx=value; + break; + + case 4: + dy=value; + break; + + case 5: + dz=value; + break; + }; + }; + template + void finalize(T& t) { + t.SetAxis(gp_Ax1(pnt,gp_Dir(dx,dy,dz))); + }; +}; + +struct gp_cylinder_accessor { + + gp_Pnt pnt; + double dx,dy,dz; + + template + Scalar get(T& t) { + switch(ID) { + case 0: + return t.Axis().Location().X(); + + case 1: + return t.Axis().Location().Y(); + + case 2: + return t.Axis().Location().Z(); + + case 3: + return t.Axis().Direction().X(); + + case 4: + return t.Axis().Direction().Y(); + + case 5: + return t.Axis().Direction().Z(); + + case 6: + return t.Radius(); + + default: + return 0; + }; + }; + template + void set(Scalar value, T& t) { + + switch(ID) { + case 0: + pnt.SetX(value); + break; + + case 1: + pnt.SetY(value); + break; + + case 2: + pnt.SetZ(value); + break; + + case 3: + dx=value; + break; + + case 4: + dy=value; + break; + + case 5: + dz=value; + break; + + case 6: + t.SetRadius(value); + break; + }; + + }; + + template + void finalize(T& t) { + t.SetAxis(gp_Ax1(pnt,gp_Dir(dx,dy,dz))); + }; +}; + +struct placement_accessor { + + double q0, q1, q2, q3; + Base::Vector3d vec; + + template + Scalar get(T& t) { + t.getRotation().getValue(q0,q1,q2,q3); + + switch(ID) { + case 0: + return q3; + + case 1: + return q0; + + case 2: + return q1; + + case 3: + return q2; + + case 4: + return t.getPosition()[0]; + + case 5: + return t.getPosition()[1]; + + case 6: + return t.getPosition()[2]; + + default: + return 0; + }; + }; + template + void set(Scalar value, T& t) { + switch(ID) { + case 0: + q3 = value; + break; + + case 1: + q0 = value; + break; + + case 2: + q1 = value; + break; + + case 3: + q2 = value; + break; + + case 4: + vec[0] = value; + break; + + case 5: + vec[1] = value; + break; + + case 6: + vec[2] = value; + break; + }; + }; + + template + void finalize(T& t) { + //need to do it at once as setting every value step by step would always normalize the rotation and + //therefor give a false value + Base::Rotation rot(q0,q1,q2,q3); + t.setRotation(rot); + t.setPosition(vec); + }; +}; + +//geometry_traits for opencascade +namespace dcm { +template<> +struct geometry_traits { + typedef tag::point3D tag; + typedef modell::XYZ modell; + typedef gp_pnt_accessor accessor; +}; +template<> +struct geometry_traits { + typedef tag::line3D tag; + typedef modell::XYZ2 modell; + typedef gp_lin_accessor accessor; +}; +template<> +struct geometry_traits { + typedef tag::plane3D tag; + typedef modell::XYZ2 modell; + typedef gp_pln_accessor accessor; +}; +template<> +struct geometry_traits { + typedef tag::cylinder3D tag; + typedef modell::XYZ2P modell; + typedef gp_cylinder_accessor accessor; +}; +template<> +struct geometry_traits { + typedef tag::part tag; + typedef modell::quaternion_wxyz_vec3 modell; + typedef placement_accessor accessor; +}; +} + +//our constraint solving system +typedef dcm::Kernel Kernel; +typedef dcm::Module3D< mpl::vector4< gp_Pnt, gp_Lin, gp_Pln, gp_Cylinder>, std::string > Module3D; +typedef dcm::ModulePart< mpl::vector1< Base::Placement >, std::string > ModulePart; + +#ifdef ASSEMBLY_DEBUG_FACILITIES +typedef dcm::System Solver; +#else +typedef dcm::System Solver; +#endif + +typedef ModulePart::type::Part Part3D; +typedef Module3D::type::Geometry3D Geometry3D; +typedef Module3D::type::Constraint3D Constraint3D; + + +#endif //SOLVER_H diff --git a/src/Mod/Assembly/App/Solver/solver_3d_ext1.cpp b/src/Mod/Assembly/App/Solver/solver_3d_ext1.cpp new file mode 100644 index 000000000..abc4ca496 --- /dev/null +++ b/src/Mod/Assembly/App/Solver/solver_3d_ext1.cpp @@ -0,0 +1,30 @@ +/* + openDCM, dimensional constraint manager + Copyright (C) 2013 Stefan Troeger + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "Solver.h" + +#ifdef DCM_EXTERNAL_CORE +#include DCM_EXTERNAL_CORE_INCLUDE_01 +DCM_EXTERNAL_CORE_01( Solver ) +#endif + +#ifdef DCM_EXTERNAL_3D +#include DCM_EXTERNAL_3D_INCLUDE_01 +DCM_EXTERNAL_3D_01( Solver ) +#endif diff --git a/src/Mod/Assembly/App/Solver/solver_3d_ext2.cpp b/src/Mod/Assembly/App/Solver/solver_3d_ext2.cpp new file mode 100644 index 000000000..1267d1e78 --- /dev/null +++ b/src/Mod/Assembly/App/Solver/solver_3d_ext2.cpp @@ -0,0 +1,25 @@ +/* + openDCM, dimensional constraint manager + Copyright (C) 2013 Stefan Troeger + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "Solver.h" + +#ifdef DCM_EXTERNAL_3D +#include DCM_EXTERNAL_3D_INCLUDE_02 +DCM_EXTERNAL_3D_02(Solver) +#endif diff --git a/src/Mod/Assembly/App/Solver/solver_3d_ext3.cpp b/src/Mod/Assembly/App/Solver/solver_3d_ext3.cpp new file mode 100644 index 000000000..80f73acc7 --- /dev/null +++ b/src/Mod/Assembly/App/Solver/solver_3d_ext3.cpp @@ -0,0 +1,25 @@ +/* + openDCM, dimensional constraint manager + Copyright (C) 2013 Stefan Troeger + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "Solver.h" + +#ifdef DCM_EXTERNAL_3D +#include DCM_EXTERNAL_3D_INCLUDE_03 +DCM_EXTERNAL_3D_03(Solver) +#endif \ No newline at end of file diff --git a/src/Mod/Assembly/App/Solver/solver_state_ext1.cpp b/src/Mod/Assembly/App/Solver/solver_state_ext1.cpp new file mode 100644 index 000000000..e1f6d0e86 --- /dev/null +++ b/src/Mod/Assembly/App/Solver/solver_state_ext1.cpp @@ -0,0 +1,44 @@ +/* + openDCM, dimensional constraint manager + Copyright (C) 2013 Stefan Troeger + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "Solver.h" + +#ifdef DCM_EXTERNAL_STATE +#include DCM_EXTERNAL_STATE_INCLUDE_001 +DCM_EXTERNAL_STATE_001( Solver ) +#endif + +#ifdef DCM_EXTERNAL_STATE +#include DCM_EXTERNAL_STATE_INCLUDE_002 +DCM_EXTERNAL_STATE_002( Solver ) +#endif + +#ifdef DCM_EXTERNAL_STATE +#include DCM_EXTERNAL_STATE_INCLUDE_003 +DCM_EXTERNAL_STATE_003( Solver ) + +#include DCM_EXTERNAL_STATE_INCLUDE_009 +DCM_EXTERNAL_STATE_009( Solver ) +#endif + +#ifdef DCM_EXTERNAL_STATE +#include DCM_EXTERNAL_STATE_INCLUDE_004 +DCM_EXTERNAL_STATE_004( Solver ) +#endif + diff --git a/src/Mod/Assembly/App/Solver/solver_state_ext2.cpp b/src/Mod/Assembly/App/Solver/solver_state_ext2.cpp new file mode 100644 index 000000000..fec3b13c6 --- /dev/null +++ b/src/Mod/Assembly/App/Solver/solver_state_ext2.cpp @@ -0,0 +1,40 @@ +/* + openDCM, dimensional constraint manager + Copyright (C) 2013 Stefan Troeger + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "Solver.h" + +#ifdef DCM_EXTERNAL_STATE +#include DCM_EXTERNAL_STATE_INCLUDE_005 +DCM_EXTERNAL_STATE_005( Solver ) +#endif + +#ifdef DCM_EXTERNAL_STATE +#include DCM_EXTERNAL_STATE_INCLUDE_006 +DCM_EXTERNAL_STATE_006( Solver ) +#endif + +#ifdef DCM_EXTERNAL_STATE +#include DCM_EXTERNAL_STATE_INCLUDE_007 +DCM_EXTERNAL_STATE_007( Solver ) +#endif + +#ifdef DCM_EXTERNAL_STATE +#include DCM_EXTERNAL_STATE_INCLUDE_008 +DCM_EXTERNAL_STATE_008( Solver ) +#endif \ No newline at end of file diff --git a/src/Mod/Assembly/App/opendcm/.kdev_include_paths b/src/Mod/Assembly/App/opendcm/.kdev_include_paths new file mode 100644 index 000000000..a97390572 --- /dev/null +++ b/src/Mod/Assembly/App/opendcm/.kdev_include_paths @@ -0,0 +1,3 @@ +/usr/include/eigen3 +/home/stefan/Projects/openDCM/opendcm/ +/home/stefan/Projects/openDCM/ diff --git a/src/Mod/Assembly/App/opendcm/core.hpp b/src/Mod/Assembly/App/opendcm/core.hpp new file mode 100644 index 000000000..a36f981e4 --- /dev/null +++ b/src/Mod/Assembly/App/opendcm/core.hpp @@ -0,0 +1,59 @@ +/* + openDCM, dimensional constraint manager + Copyright (C) 2012 Stefan Troeger + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef DCM_CORE_H +#define DCM_CORE_H + +#ifdef _WIN32 + //warning about to long decoraded names, won't affect the code correctness + #pragma warning( disable : 4503 ) + //warning about changed pod initalising behaviour (boost blank in variant) + #pragma warning( disable : 4345 ) + //warning about multiple assignemnt operators in Equation + #pragma warning( disable : 4522 ) + + //disable boost concept checks, as some of them have alignment problems which bring msvc to an error + //(for example DFSvisitor check in boost::graph::depht_first_search) + //this has no runtime effect as these are only compile time checks + #include + #undef BOOST_CONCEPT_ASSERT + #define BOOST_CONCEPT_ASSERT(Model) + #include + +#endif + +#include "core/defines.hpp" +#include "core/geometry.hpp" +#include "core/kernel.hpp" +#include "core/system.hpp" + + +#ifdef DCM_EXTERNAL_CORE + +#define DCM_EXTERNAL_CORE_INCLUDE_01 "opendcm/core/imp/system_imp.hpp" +#define DCM_EXTERNAL_CORE_01( Sys )\ + template class dcm::System; \ + template struct dcm::Equation, 1>; \ + template struct dcm::Equation; \ + template struct dcm::Equation, 3, dcm::rotation>; + +#endif //external + +#endif //DCM_CORE_H + diff --git a/src/Mod/Assembly/App/opendcm/core/clustergraph.hpp b/src/Mod/Assembly/App/opendcm/core/clustergraph.hpp new file mode 100644 index 000000000..3e4a599f2 --- /dev/null +++ b/src/Mod/Assembly/App/opendcm/core/clustergraph.hpp @@ -0,0 +1,1093 @@ +/* + openDCM, dimensional constraint manager + Copyright (C) 2012 Stefan Troeger + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef CLUSTERGRAPH_HPP +#define CLUSTERGRAPH_HPP + +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "property.hpp" + +#include + +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; + +namespace dcm { + +/** @addtogroup Core + * @{ + * */ + +/** @addtogroup ClusterGraph + * @{*/ + +namespace details { + +/** @addtogroup Metafunctions + * @{*/ + +/** + * @brief Creates a fusion::vector of boost shared_ptr's from the given types + * + * Creates a shared pointer sequence (sps) of the supplied types by converting them to + * boost::shared_ptr's first and creating a fusion::vector of all pointers afterwards which can be + * accessed by the type typedef. Usage: @code sps::type @endcode + * + * @tparam seq the mpl::sequence with the types to convert to shared_ptr's + **/ +template +struct sps { //shared_ptr sequence + typedef typename mpl::transform >::type spv; + typedef typename fusion::result_of::as_vector::type type; +}; +/**@}*/ + +//Define vertex and edge properties which are always added for use in the boost graph library algorithms +//which are used in the ClusterGraph implementation +typedef mpl::vector1 bgl_v_props; +typedef mpl::vector1 bgl_e_props; + +typedef boost::adjacency_list_traits list_traits; + + +/** + * @brief A type to be used as identifier for vertices and edges + * + * Vertices and edges need to be identified in a stable(safe/load), unique(over multiple clusters) and + * comparable manner. The bgl vertex and edge discriptors don't fullfill this need as they have a direct + * relation to the graphs storage. Therefore they change value on moving entitiys to diffrent clusters or + * clone actions. This class is used to overcome this problem. + **/ +typedef int universalID; + +/** + * @brief Generator for unique identifiers + * + * The universalID used to identify vertices and edges globaly need to be unique and therefore can't be + * created at good will. This generator creates universalID's in a incremental manner and is intended to + * to be shared between all graphs of a system, so that all created ID's are unique. + **/ +struct IDgen { + universalID* counter; + + IDgen() { + counter = new universalID(10); + }; + IDgen(universalID id) { + counter = new universalID(id); + }; + ~IDgen() { + delete counter; + }; + /** + * @brief Generates a new unique ID + * + * @return :details::universalID + **/ + universalID generate() { + return ++ (*counter); + }; + /** + * @brief Returns the amount if generated ID's + * + * As universalID's are integers the returned count is a ID and can therefore also be used as the last + * created ID. + * + * @return :details::universalID + **/ + universalID count() { + return (*counter); + }; + /** + * @brief Set the current value for incremental creation + * + * ID's are created incrementaly and if a specific startingpoint is wished it can be set here by + * supplying the last created ID or the amount of totaly created ID's + * + * @param id The last created ID + * @return void + **/ + void setCount(universalID id) { + *counter = id; + }; +}; + +/** + * @brief Exception thrown from the graph at any occuring error + **/ +struct cluster_error : virtual boost::exception {}; + +/** + * @brief Pointer type to share a common ID generator @ref IDgen + **/ +typedef boost::shared_ptr IDpointer; + +} + +/** @name Descriptors */ +/**@{ + * @brief Identifier for local vertices + * + * The boost graph library works with identifiers for vertices which directly relate to there storage. + * Therefore they can be used only in the relevant cluster, they are local. These are the descriptors + * which need to be used for all bgl algorithms. + **/ +typedef details::list_traits::vertex_descriptor LocalVertex; + +/** + * @brief Indentifier for local edge + * + * The boost graph library works with identifiers for edges which directly relate to there storage. + * Therefore they can be used only in the relevant cluster, they are local. These are the descriptors + * which need to be used for all bgl algorithms. + **/ +typedef details::list_traits::edge_descriptor LocalEdge; + +/** + * @brief Identifier for global vertex + * + * To overcome the locality of the bgl vertex descriptors a global alternative is introduced. This descriptor + * is unique over clusters and stable on moves and clones. + **/ +typedef details::universalID GlobalVertex; + +/** + * @brief Identifier for global edge + * + * To overcome the locality of the bgl edge discriptors a global alternative is introduced. This descriptor + * is unique over clusters and stable on moves and clones. It holds it's source and target also as global + * descriptors of type GlobalVertex and has a unique ID in form of a universalID assigned. + **/ +struct GlobalEdge { + GlobalVertex source; + GlobalVertex target; + details::universalID ID; + + bool operator== (const GlobalEdge& second) const { + return ID == second.ID; + }; + bool operator!= (const GlobalEdge& second) const { + return ID != second.ID; + }; + bool valid() { + return ID > 9; + }; +}; +/**@}*/ + + +/** + * @brief A graph that can be stacked in a tree-like manner without loosing it connections + * + * This is basicly a boost adjacency_list with single linked lists 'listS' as storage for vertices and + * edges. The edges are undirected. This allows to use all boost graph algorithms and provides therefore + * an comprehensive way for analysing and manipulating its content. It further extends the class with the + * possibility to cluster its content and to add properties and objects to all entitys. For more + * information, see the module ClusterGraph + * + * @tparam edge_prop a mpl::vector with properties which are added to local edges + * @tparam vertex_prop a mpl::vector with properties which are added to vertices + * @tparam cluster_prop a mpl::vector with properties which are added to all clusters + * @tparam objects a mpl::vector with all object types which shall be stored at vertices and edges + **/ +template< typename edge_prop, typename vertex_prop, typename cluster_prop, typename objects> +class ClusterGraph : public boost::adjacency_list < boost::listS, boost::listS, + boost::undirectedS, + fusion::vector < GlobalVertex, + typename details::pts< typename details::ensure_properties::type >::type, + typename details::sps::type > , + fusion::vector < typename details::pts< typename details::ensure_properties::type >::type, + std::vector< fusion::vector< typename details::sps::type, GlobalEdge > > > > , +public PropertyOwner::type>, +public boost::noncopyable, + public boost::enable_shared_from_this > { + +public: + /** + * @brief mpl::vector with all edge properties + * + * The edge properties supplied as template argument to the ClusterGraph are extended with graph + * specific properties, for example a edge_index_prop. These extra properties are intendet to be + * used with boost graph algorithms as property maps. They need to be in specefied by the ClusterGraph + * as they are used within it's implementation. If the graph specific properties are already a part + * of the given property sequence, nothing happens, they are not added twice. + **/ + typedef typename details::ensure_properties::type edge_properties; + /** + * @brief mpl::vector with all vertex properties + * + * The vertex properties supplied as template argument to the ClusterGraph are extended with graph + * specific properties as vertex_index_prop. These extra properties are intendet to be + * used with boost graph algorithms as property maps. They need to be in specefied by the ClusterGraph + * as they are used within it's implementation.If the graph specific properties are already a part + * of the given property sequence, nothing happens, they are not added twice. + **/ + typedef typename details::ensure_properties::type vertex_properties; + + /** + * @brief The property bundle for GlobalEdges + * + * A local edge in a cluster can hold multiple gloabal ones. Therefor we need an extra bundle for + * the GlobalEdges. This bundle holds the objects which are added to that global edge and it's identifier. + * Note that global edges don't have properties, these are only for local ones. + **/ + typedef fusion::vector< typename details::sps::type, GlobalEdge > edge_bundle_single; + /** + * @brief The property bundle for local edges + * + * Local edges can hold multiple global ones, we therefore need a std::vector of global edges. As + * they are fully described by a edge_bundle_single we store those. Also local edges can have properties, + * so store a fusion sequence of them too. + **/ + typedef fusion::vector< typename details::pts::type, std::vector< edge_bundle_single > > edge_bundle; + /** + * @brief Iteator to access all edge_bundle_single stored in a edge_bundle + **/ + typedef typename std::vector< edge_bundle_single >::iterator edge_single_iterator; + /** + * @brief Property bundle for local vertices + * + * This bundle is simpler than the edge one, as every vertex has on single bundle. We therefore + * store the global descriptor for identification, the fusion sequence with the properties and + * the objects all in one bundle. + **/ + typedef fusion::vector < GlobalVertex, typename details::pts::type, + typename details::sps::type > vertex_bundle; + + /** + * @brief The adjacency_list type ClusterGraph inherited from + **/ + typedef boost::adjacency_list < boost::listS, boost::listS, + boost::undirectedS, vertex_bundle, edge_bundle > Graph; + + typedef boost::enable_shared_from_this > sp_base; + + //if changed_prop is not a property we have to add it now + typedef typename details::ensure_property::type cluster_properties; + + typedef typename boost::graph_traits::vertex_iterator local_vertex_iterator; + typedef typename boost::graph_traits::edge_iterator local_edge_iterator; + typedef typename boost::graph_traits::out_edge_iterator local_out_edge_iterator; + + typedef std::map > ClusterMap; + + + struct global_extractor { + typedef GlobalEdge& result_type; + template + result_type operator()(T& bundle) const; + }; + + struct global_vertex_extractor { + typedef GlobalVertex result_type; + ClusterGraph& graph; + global_vertex_extractor(ClusterGraph& g); + result_type operator()(LocalVertex& v) const; + }; + + template + struct object_extractor { + + typedef boost::shared_ptr base_type; + typedef base_type& result_type; + typedef typename mpl::find::type iterator; + typedef typename mpl::distance::type, iterator>::type distance; + BOOST_MPL_ASSERT((mpl::not_::type > >)); + + result_type operator()(vertex_bundle& bundle) const; + result_type operator()(edge_bundle_single& bundle) const; + }; + + //iterators + /** + * @brief Iterator for global edge descriptors \ref GlobalEdge + **/ + typedef boost::transform_iterator global_edge_iterator; + + /** + * @brief Iterator for global vertex descriptor \ref GlobalVertex + **/ + typedef boost::transform_iterator global_vertex_iterator; + + /** + * @brief Iterator for objects of given type + * + * Allows to iterate over all objects of given type, dereferencing gives the boost::shared_ptr + * + * @tparam Obj the object type to iterate over + **/ + template + struct object_iterator : public boost::transform_iterator, edge_single_iterator> { + object_iterator(edge_single_iterator it, object_extractor f) + : boost::transform_iterator, edge_single_iterator> (it, f) {}; + }; + + /** + * @brief Iterator for clusters + * + * Allows to iterate over all subclusters. + **/ + typedef typename ClusterMap::iterator cluster_iterator; + /** + * @brief Const equivalent to \ref cluster_iterator + **/ + typedef typename ClusterMap::const_iterator const_cluster_iterator; + + /** + * @brief Basic constructor + * + * This constructor creates a empty cluster with a new ID generator. This is to be used on initial + * clustergraph creation, so only for the very first cluster. + **/ + ClusterGraph() : m_id(new details::IDgen) {}; + + /** + * @brief Dependent constructor + * + * This constructor creates a new cluster, but uses the given cluster as parent. It will therefore + * create a tree-like relationship. Be aware, that the new cluster is not added to the parents + * subcluster list, that has to be done manualy. The new cluster shares the parents ID generator. + * + * @param g the parent cluster graph + **/ + ClusterGraph(boost::shared_ptr g) : m_parent(g), m_id(new details::IDgen) { + if(g) + m_id = g->m_id; + }; + + ~ClusterGraph() {}; + + /** + * @brief Copys the Clustergraph into a new one + * + * Copys this cluster and all subclusters into the give one, which is cleared bevore copying. Be + * aware that all objects and properties are only copied, and as some are shared pointers (namely + * all objects) you may have to clone them. If needed this can be done with the supplied functor, + * which receives all copied objects to his function operator which returns the new object. + * @param into The Graph that should be a copy of this + * @param functor The function objects which gets the graph objects and returns the ones for the + * copied graph + */ + template + void copyInto(boost::shared_ptr into, Functor& functor) const; + + /** + * @brief Compare by adress, not by content + * @param other the cluster to compare with + * @return bool if this is the same cluster in memory + **/ + template + bool operator== (const T& other) const; + + /** + * @brief Compare by adress, not by content + * @param other the cluster to compare with + * @return bool if this is the not same cluster in memory + **/ + template + bool operator!= (const T& other) const; + + /** + * @brief Set diffrent behaviour for changed markers + * + * Some methods of the ClusterGraph set it's changed_prop to true. Thats sensible, as they change + * the graph. However, there are situations where you want to use the methods but don't want the change + * marked. For example recreations while cloning. This method can be used to disable the changed setting. + * @param on Turn change markers on or of + * @return void + **/ + void setCopyMode(bool on); + + //Make sure the compiler finds the base class setters even with equal named functions in this class + using PropertyOwner::getProperty; + using PropertyOwner::setProperty; + + /** + * @brief Set the property of a owned cluster + * + * Makes it easy to set a property of a subcluster without retrieving it first + * + * @tparam P the property type which shall be set + * @param v the local vertex which describes the subcluster + **/ + template + typename P::type& getSubclusterProperty(LocalVertex v); + + /** + * @brief Mark if the cluster was changed + * + * @return void + **/ + void setChanged(); + + + /* ******************************************************* + * Subclustering + * *******************************************************/ + + /** + * @brief Creates a new subcluster + * + * As clusters can be stacked in a tree like manner, this function can be used to create new + * children. It automaticly adds it to the subcluster list and adds it to the graph. The new + * subcluster is fully defined by its object and the vertex descriptor which is it's position + * in the current cluster. + * + * @return :pair< boost::shared_ptr< ClusterGraph >, LocalVertex > Subcluster and its descriptor + **/ + std::pair, LocalVertex> createCluster(); + + /** + * @brief Returns the parent cluster + * + * In the stacked cluster hirarchy most clusters have a parent whcih can be accessed with this function. + * However, the toplevel cluster dos nothave a parent and a empty shared_ptr is returned. + * + * @return :shared_ptr< ClusterGraph > the parent cluster or empty pointer + **/ + boost::shared_ptr parent(); + + /** + * @brief const version of \ref parent() + * + * @return :shared_ptr< ClusterGraph > + **/ + const boost::shared_ptr parent() const; + + /** + * @brief Is this the toplevel cluster? + * + * @return bool if it is + **/ + bool isRoot() const; + + /** + * @brief Returns the toplevel cluster + * + * @return :shared_ptr< ClusterGraph > + **/ + boost::shared_ptr root(); + + /** + * @brief const equivalent of \ref root() + * + * @return :shared_ptr< ClusterGraph > + **/ + const boost::shared_ptr root() const; + + /** + * @brief Iterators for all subclusters + * + * A pair with two \ref cluster_iterator is returned which point to the first cluster and + * to one after the last. #this allows full iteration over all subclusters + * + * @return :pair< cluster_iterator, cluster_iterator > + **/ + std::pair clusters(); + + /** + * @brief const equivalent to \ref clusters() + * + * @return :pair< const_cluster_iterator, const_cluster_iterator > + **/ + std::pair clusters() const; + + /** + * @brief The amount of all subclusters + * + * @return :size_t + **/ + std::size_t numClusters() const; + + /** + * @brief Check if this vertex is a cluster + * + * A subcluster is added as normal vertex to the parent cluster. There is no way to distinguish + * between clusters and normal vertices with global or local descriptors only. Therefore this + * function can be used to get information about the type. If it is a cluster, it can be accessed + * with \ref getVertexCluster + * + * @param v The vertex to be checked + * @return bool is cluster or not + **/ + bool isCluster(const dcm::LocalVertex v) const; + + /** + * @brief Get the cluster corresponding the discriptor + * + * A subcluster is added as normal vertex to the parent cluster. There is no way to access + * the clusters object with global or local descriptors only. Therefore this + * function can be used to get the object belonging to the descriptor. If the vertex is not + * a cluster an empty pointer is returned. + * + * @param v The vertex for which the cluster is wanted + * @return boost::shared_ptr the coresponding cluster orempty pointer + **/ + boost::shared_ptr getVertexCluster(LocalVertex v); + + /** + * @brief Get the vertex descrptor which descripes the clusters position in the graph + * + * This function is the inverse to \ref getVertexCluster + * + * @param g the graph for which the vertex is searched + * @return :LocalVertex + **/ + LocalVertex getClusterVertex(boost::shared_ptr g); + + /** + * @brief Convinience function for \ref removeCluster + **/ + template + void removeCluster(boost::shared_ptr g, Functor& f); + /** + * @brief Convinience function for \ref removeCluster + **/ + void removeCluster(boost::shared_ptr g); + /** + * @brief Delete all subcluster + * + * @return void + **/ + + void clearClusters(); + + /** + * @brief Remove a subcluster and applys the functor to all removed edges and vertices + * + * All downstream elements of the local vertex v will be removed after the functor is applied to there + * edges and vertices. Note that the LocalVertex which represents the cluster to delete is not passed + * to the functor. When ever the cluster is changed it will be passed to the functor, so that it need + * to have three overloads: operator()(GlobalEdge), operator()(GlobalVertex), operator()(ClusterGraph&) + * + * @param v Local vertex which is a cluster and which should be deleted + * @param f Functor to apply on all graph elements + */ + template + void removeCluster(LocalVertex v, Functor& f); + void removeCluster(LocalVertex v); + +protected: + template + void remove_vertices(Functor& f, bool recursive = false); + + + /* ******************************************************* + * Creation Handling + * *******************************************************/ + +public: + /** + * @brief Add a vertex to the local cluster + * + * @return fusion::vector the local and global vertex descriptor + **/ + fusion::vector addVertex(); + + /** + * @brief Add a vertex to the local cluster with given global identifier + * + * Sometimes it is needed to add a vertex with given global identifier. As the global vertex can not + * be changed after creation, this method can be used to specify the global vertex by which this + * graph vertex can be identified. The given global vertex is not checked, you need to ensure that + * it is a unique id or the already existing vertex is returned. + * The ID generator is changed so that it creates only identifier bigger than v. + * + * @return fusion::vector the local and global vertex descriptor + **/ + fusion::vector addVertex(GlobalVertex v); + + /** + * @brief Iterators of all global vertices in this cluster + * + * Returns the iterator for the first global vertex and the end() iterator as reference for + * iterating + * + * @return std::pair< global_vertex_iterator, global_vertex_iterator > global vertex iterators + **/ + std::pair globalVertices(); + + /** + * @brief Returns the edge between the local vertices + * + * This function is the same as boost::edge(source, target, Graph) and only added for convienience. + * + * @param source LocalEdge as edge source + * @param target LocalEdge as edge target + * @return std::pair with the local edge descriptor if existing. The bool value shows if the + * edge exists or not + **/ + std::pair edge(LocalVertex source, LocalVertex target); + + /** + * @brief Add a edge between two vertices, defined by local descriptors. + * + * Add an edge that connects the two vertices and in the local clustergraph and assign the GlobalEdge to it. The + * LocalVertex parameters should not represent a cluster which would result in the functions failure. If there's + * already a local edge between the vertices a new global edge will be added and returned. Failure will be + * recocnisable by a false value in the returned type sequence. + * + * @param source The first vertex the edge should connect + * @param target The second vertex the edge should connect + * @return fusion::vector with the local and global descriptors of the edge and an bool + * value indicationg the successful creation. + **/ + fusion::vector addEdge(LocalVertex source, LocalVertex target); + + /** + * @brief Add a edge between two vertices, defined by global descriptors. + * + * Adds an edge between vertices which are not nesseccarily in this local cluster and have therefore to be + * identified with global descriptors. The only condition for source and target vertex is that both must be + * in the local cluster or any of its subclusters. If thats not the case, the function will fail. On success + * a new GlobalEdge will be created, but not neccessarily a local one. If the vertices are in different cluster + * which are already connected the global edge will be added to this connecting local edge. Thats the one returned + * in the seqence. Note that it's possible that the local edge belongs to another subcluster and therefore can't be + * used in the local cluster. This case is indicated by the scope return value. + * + * @param source The first vertex the edge should connect + * @param target The second vertex the edge should connect + * @return fusion:vector< LocalEdge, GlobalEdge, success, scope > with the new global edge descriptor and the local + * one where it was added. Success indicates if the function was successful and scope shows the validy of the local + * descriptor in this cluster (true means the edge is in this cluster). + **/ + fusion::vector addEdge(GlobalVertex source, GlobalVertex target); + + fusion::vector addEdgeGlobal(GlobalVertex source, GlobalVertex target); + + /** + * @brief Get an iterator to all the global edges hold by this local edge + * + * Local edges can hold multiple global ones, for example when they connect at least one cluster. Therefore a direct + * LocalEdge - GlobalEdge mapping is not possible. Instead you can access all GlobalEdge's hold by this local one in + * a normal iterating manner. + * + * @param e the local edge for which the global descriptors are wanted + * @return std::pair with the global_edge_iterator's pointing to the vector's start + * and end + **/ + std::pair getGlobalEdges(LocalEdge e); + + /** + * @brief Get the count of all global edges + * + * Local edges can hold multiple global ones, for example when they connect at least one cluster. To get the + * number of all global edges in this local one you can use this function. + * + * @param e the local edge for which the global descriptors are wanted + * @return std::pair with the global_edge_iterator's pointing to the vector's start + * and end + **/ + int getGlobalEdgeCount(LocalEdge e); + + /** + * @brief Get the local edge which holds the specified global edge. + * + * Note that GlobalEdge must be in a local edge of this cluster, means the connected vertices must be in this + * or one of it's subclusters (but not the same). Also if the containing LocalEdge is not in this cluster, but in one of it's + * subclusters, the function fails and the returned edge is invalid. + * + * @param e GlobalEdge for which the containing local one is wanted + * @return std:pair< LocalEdge, bool > with the containing LocalEdge and a bool indicator if function was successful. + **/ + std::pair getLocalEdge(GlobalEdge e); + + /** + * @brief Get the local edge which holds the specified global one and the subcluster in which it is valid. + * + * The function only fails when the global edge is hold by a local one upstream in the cluster + * herarchy. + * + * @param e GlobalEdge for which the containing local one is wanted + * @return fusion::vector with the containing LocalEdge, the cluster which holds it and a bool indicator if function was successful. + **/ + fusion::vector getLocalEdgeGraph(GlobalEdge e); + + /** + * @brief Get the GlobalVertex assiociated with this local one. + * + * @param v LocalVertex + * @return GlobalVertex + **/ + GlobalVertex getGlobalVertex(LocalVertex v) const; + + /** + * @brief Get the LocalVertex which corresponds to the golab one + * + * The GlobalVertex has to be in this cluster or any of it's subclusters. If its in a subcluster, the returned + * LocalVertex will represent this cluster. If the GlobalVertex is not in this clusters scope the function fails. + * + * @param vertex GlobalVertex for which the local one shall be returned + * @return std::pair< LocalVertex, bool > The LocalVertex containing the global one and an success indicator + **/ + std::pair getLocalVertex(GlobalVertex vertex); + + /** + * @brief Get the local vertex which holds the specified global one and the subcluster in which it is valid. + * + * The function only fails when the global vertex is hold by a local one upstream in the cluster + * herarchy. + * + * @param v GlobalVertex for which the containing local one is wanted + * @return fusion::vector with the containing LocalVertex, the cluster which holds it and a bool indicator if function was successful. + **/ + fusion::vector, bool> getLocalVertexGraph(GlobalVertex v); + + + /* ******************************************************* + * Remove Handling + * *******************************************************/ +private: + + template + void downstreamRemoveVertex(GlobalVertex v, Functor& f); + + void simpleRemoveEdge(LocalEdge e); + + +public: + /** + * @brief Removes a vertex from the local cluster and applys functor to removed edges + * + * Removes the vertex from the local graph and invalidates the global vertex id. Also all edges connecting + * to this vertex will be removed after the functor was applied to them. The functor needs to implement + * operato()(GlobalEdge e). Remark that there is no checking done if the vertex is a cluster, so you + * need to make sure it's not, as removing a clustervertex will not delete the coresponding cluster. + * + * @param id Local Vertex which should be removed from the graph + * @param f functor whose operator(GlobalEdge) is called for every removed edge + **/ + template + void removeVertex(LocalVertex id, Functor& f); + //no default template arguments for template functions allowed before c++0x, so a little workaround + void removeVertex(LocalVertex id) ; + + /** + * @brief Removes a vertex from the cluster or it's subclusters and applys functor to removed edges + * + * Removes the vertex from the graph or subclusters and invalidates the global vertex id. Also all edges connecting + * to this vertex will be removed (upstream and downstream) after the functor was applied to them. The functor + * needs to implement operato()(LocalEdge edge). + * + * @param id Global Vertex which should be removed from the graph + * @param f functor whose operator(LocalEdge) is called on every removed edge + **/ + template + void removeVertex(GlobalVertex id, Functor& f); + //no default template arguments for template functions allowed before c++0x, so a little workaround + void removeVertex(GlobalVertex id); + + /** + * @brief Removes a global Edge from the cluster or it's subclusters + * + * Removes the edge from the graph or subclusters and invalidates the global edge id. If the local edge holds + * only this global one it will be removed also. + * + * @param id Global Edge which should be removed from the graph + * @return bool indicates if the global id could be removed + **/ + void removeEdge(GlobalEdge id); + + /** + * @brief Removes a local edge from the cluster and calls the functor for all removed global edges + * + * Removes the edge from the graph and invalidates the global edges. The Functor needs to provide + * operator()(GlobalEdge). If no functor is needed just use boost::remove_edge. + * + * @param id Global Edge which should be removed from the graph + * @param f functor whoms operator(GlobalEdge) is called + * @return bool indicates if the global id could be removed + **/ + template + void removeEdge(LocalEdge id, Functor& f); + + + /* ******************************************************* + * Object Handling + * *******************************************************/ +public: + + /** + * @brief Get the desired object at the specified vertex or edge + * + * This function allows to access the objects stored in the graph. If no object of the desired type + * was set before, a empty shared_ptr will be returned. Accessing the object at a local edge is a special + * case, as it can hold many global edges, each with it's own objetcs. Using a LocalEdge as key will + * always return the object for the first GlobalEdge. + * + * @tparam Obj the object type which shall be returned + * @param k local or global Vertex/Edge descriptor for which the object is desired + * @return shared_ptr< Obj > the pointer to the desired object + **/ + template + boost::shared_ptr getObject(key k); + + /** + * @brief Set a object at the specified vertex or edge + * + * Sets the given value at the given key. Note that every entity can hold only one object, so setting + * a new value resets all other objects which were set before. Setting the object at a local edge is a special + * case, as it can hold many global edges, each with it's own objects. Using a LocalEdge as key will + * always set the object for the first GlobalEdge. + * + * @tparam Obj the object type which shall be set + * @param k local or global Vertex/Edge descriptor for which the object should be set + * @param val the object which should be stored + * @return void + **/ + template + void setObject(key k, boost::shared_ptr val); + + /** + * @brief Get iterator range for all GlobalEdge objects hold by this local edge + * + * LocalEdge's can hold multiple global ones and the iterators can be used to access a specific object type in + * all global edges hold by this local edge. + * + * @tparam Obj the object type over which it shall be iterated + * @param k the LocalEdge over which all Objects should be iterated. + * @return pair< begin, end > the iterator rang from begin (first element) to end (first undefined element) + **/ + template + std::pair< object_iterator, object_iterator > getObjects(LocalEdge k); + + /** + * @brief Applys the functor to each occurence of an object + * + * Each valid object of the given type is extractet and passed to the function object. Vertices + * and edges are searched for valid object pointers, it happens in this order. When a recursive + * search is specified, all subclusters are searched too, but the cluster is passt to the Functor + * first. So make sure a function overload for clusters exist in this case. + * + * @tparam Obj the object type for which the functor shall be used + * @param f the functor to which all valid objects get passed to. + * @param recursive specifies if the subclusters should be searched for objects too + **/ + template + void for_each(Functor& f, bool recursive = false); + + /** + * @brief Applys the functor to each object + * + * Each valid object of any type is extractet and passed to the function object. Vertices + * and edges are searched for valid object pointers, it happens in this order. When a recursive + * search is specified, all subclusters are searched too, but the cluster is passt to the Functor + * first. So make sure a function overload for clusters exist in this case. + * + * @param f the functor to which all valid objects get passed to. + * @param recursive specifies if the subclusters should be searched for objects too + **/ + template + void for_each_object(Functor& f, bool recursive = false); + + /* ******************************************************* + * Property Handling + * *******************************************************/ + + /** + * @brief Get the desired property at the specified vertex or edge + * + * This function allows to access the properties stored in the graph. If no property of the desired type + * was set before, a default construced will be returned. Accessing the property at a global edge will return + * the property of the holding local edge. + * + * @tparam property the property type which shall be returned + * @param k local or global Vertex/Edge descriptor for which the property is desired + * @return property::type& the reference to the desired property + **/ + template + typename property::type& getProperty(key k); + + /** + * @brief Set a property at the specified vertex or edge + * + * Sets the given value at the given key. Note that every entity can hold one of each property, as opposed + * to objects. Setting the property at a local edge is a special case, as it can hold many global edges, + * each with it's own propertys. Using a LocalEdge as key will always set the property for the first GlobalEdge. + * + * @tparam property the property type which shall be set + * @param k local or global Vertex/Edge descriptor for which the property should be set + * @param val the property value which should be stored + * @return void + **/ + template + void setProperty(key k, typename property::type val); + + /** + * @brief recreate the internal index maps for edges and vertices + * + * Quite many boost graph algorithms need the indices for vertices and edges which are provided by property + * maps. As we use list, and not vector, as underlaying storage we don't get that property for free and + * need to create it ourself. To ease that procedure the internal property vertex_index_prop and edge_index_prop + * can be used as property maps and can be initialized by calling this function. + * + * @return void + **/ + void initIndexMaps(); + + + + /******************************************************** + * Vertex and Cluster moving + * *******************************************************/ + + /** + * @brief Move a vertex to a subcluster + * + * Overloaded convinience function which fetches the local descriptor for the cluster reference and calls + * the full parameter equivalent. Both cluster and vertex must be in the local cluster. + * + * @param v the LocalVertex to be moved + * @param cg reference to the subcluster to which v should be moved + * @return LocalVertex the local descriptor of the moved vertex in the subcluster + **/ + LocalVertex moveToSubcluster(LocalVertex v, boost::shared_ptr cg); + + /** + * @brief Move a vertex to a subcluster + * + * Overloaded convinience function which fetches the the cluster reference for the local descriptor and calls + * the full parameter equivalent. Both cluster and vertex must be in the local cluster. + * + * @param v the LocalVertex to be moved + * @param Cluster the local vertex descriptor representing the subcluster to which v should be moved + * @return LocalVertex the local descriptor of the moved vertex in the subcluster + **/ + LocalVertex moveToSubcluster(LocalVertex v, LocalVertex Cluster); + + /** + * @brief Move a vertex to a subcluster + * + * This function moves the LocalVertex to the subcluster and reconnects all other vertices and clusters. The + * moved vertex will hold it's global descriptor but get a new local one assigned (the one returned). The same + * stands for all edges which use the moved vertex: global descriptors stay the same, but they are moved to new + * local edges. It's allowed to move cluster vertices with this function. + * The specified cluster has of course to be a valid and direct subcluster, the move vertex also has to be in the + * local cluster. + * + * @param v the LocalVertex to be moved + * @param Cluster the local vertex descriptor representing the subcluster to which v should be moved + * @param cg reference to the subcluster to which v should be moved + * @return LocalVertex the local descriptor of the moved vertex in the subcluster + **/ + LocalVertex moveToSubcluster(LocalVertex v, LocalVertex Cluster, boost::shared_ptr cg); + + + /** + * @brief Move a vertex to the parent cluster. + * + * This function moves a vertex one step up in the subcluster hierarchie and reconnects all other vertices and clusters. + * The moved vertex will hold it's global descriptor but get a new local one assigned (the one returned). The same + * stands for all edges which use the moved vertex: global descriptors stay the same, but they are moved to new + * local edges. Note that this function is the inverse of moveToSubcluster, and doing Pseudocode: + * moveToParent(moveToSubcluster(v)) does nothing (only the local descriptor of the moved vertex is + * diffrent afterwards). + * + * @param v Local vertex which should be moved to the parents cluster + * @return LocalVertex the local descriptor of the moved vertex, valid in the parent cluster only. + **/ + LocalVertex moveToParent(LocalVertex v); + + + /******************************************************** + * Stuff + * *******************************************************/ + + ClusterMap m_clusters; + int test; + +protected: + boost::weak_ptr m_parent; + details::IDpointer m_id; + bool copy_mode; //no changing itself when copying + + + /* Searches the global vertex in all local vertices of this graph, and returns the local + * one which holds the global vertex. If not successfull the local vertex returned will be + * invalid and the bool parameter will be false. If recursive = true, all subclusters will + * be seached too, however, if found there the retourned local vertex will be the vertex + * representing the toplevel cluster holding the global vertex in the initial graph. + * */ + std::pair getContainingVertex(GlobalVertex id, bool recursive = true); + + /* Searches the local vertex holding the specified global one in this and all it's subclusters. + * If found, the holding local vertex and the graph in which it is valid will be returned. + * */ + fusion::vector, bool> getContainingVertexGraph(GlobalVertex id); + + /* Searches the global edge in all local edges of this graph, and returns the local + * one which holds the global edge. If not successfull the local edge returned will be + * invalid and the bool parameter will be false. + * */ + std::pair getContainingEdge(GlobalEdge id); + + /* Searches the local edge holding the specified global one in this and all it's subclusters. + * If found, the holding local edge and the graph in which it is valid will be returned. + * */ + fusion::vector getContainingEdgeGraph(GlobalEdge id); + + template + typename functor::result_type apply_to_bundle(LocalVertex k, functor f); + + template + typename functor::result_type apply_to_bundle(LocalEdge k, functor f); + + template + typename functor::result_type apply_to_bundle(GlobalVertex k, functor f); + + template + typename functor::result_type apply_to_bundle(GlobalEdge k, functor f); + +public: + //may hold cluster properties which have Eigen3 objects and therefore need alignment + EIGEN_MAKE_ALIGNED_OPERATOR_NEW +}; + +/** @} */ +/** @} */ + +} //namespace dcm + + +#ifndef DCM_EXTERNAL_CORE +#include "imp/clustergraph_imp.hpp" +#endif + +#endif // CLUSTERGRAPH_HPP + + + + diff --git a/src/Mod/Assembly/App/opendcm/core/constraint.hpp b/src/Mod/Assembly/App/opendcm/core/constraint.hpp new file mode 100644 index 000000000..7fcc1b9d5 --- /dev/null +++ b/src/Mod/Assembly/App/opendcm/core/constraint.hpp @@ -0,0 +1,326 @@ +/* + openDCM, dimensional constraint manager + Copyright (C) 2012 Stefan Troeger + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more detemplate tails. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef GCM_CONSTRAINT_H +#define GCM_CONSTRAINT_H + + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include "traits.hpp" +#include "object.hpp" +#include "equations.hpp" +#include "geometry.hpp" + +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; + +namespace dcm { + +namespace detail { + +//metafunction to avoid ot-of-range access of mpl sequences +template +struct in_range_value { + typedef typename mpl::prior >::type last_id; + typedef typename mpl::min< mpl::int_, last_id>::type type; +}; + +//type erasure container for constraints +template +class Constraint { + + typedef typename Sys::Kernel Kernel; + typedef typename Kernel::number_type Scalar; + typedef typename Kernel::DynStride DS; + typedef typename Kernel::MappedEquationSystem MES; + + typedef boost::shared_ptr > geom_ptr; + typedef std::vector > Vec; + + //metafunction to create equation from consraint and tags + template + struct equation { + typedef typename C::template type type; + }; + +public: + Constraint(geom_ptr f, geom_ptr s); + ~Constraint(); + + //workaround until better analysing class is created + // TODO: remove diasable once analyser is available + void disable() { + content->disable(); + }; + + std::vector getGenericEquations(); + std::vector getGenericConstraints(); + std::vector getEquationTypes(); + std::vector getConstraintTypes(); + + template + void initializeFromTags(ConstraintVector& obj); + template + void initialize(ConstraintVector& obj); + +protected: + //initialising from geometry functions + template + void initializeFirstGeometry(ConstraintVector& cv, boost::mpl::false_); + template + void initializeFirstGeometry(ConstraintVector& cv, boost::mpl::true_); + template + void initializeSecondGeometry(ConstraintVector& cv, boost::mpl::false_); + template + void initializeSecondGeometry(ConstraintVector& cv, boost::mpl::true_); + template + inline void intitalizeFinalize(ConstraintVector& cv, boost::mpl::false_); + template + inline void intitalizeFinalize(ConstraintVector& cv, boost::mpl::true_); + + + int equationCount(); + void calculate(Scalar scale, AccessType access = general); + void treatLGZ(); + void setMaps(MES& mes); + void collectPseudoPoints(Vec& vec1, Vec& vec2); + + //Equation is the constraint with types, the EquationSet hold all needed Maps for calculation + template + struct EquationSet { + EquationSet() : m_diff_first(NULL,0,DS(0,0)), m_diff_first_rot(NULL,0,DS(0,0)), + m_diff_second(NULL,0,DS(0,0)), m_diff_second_rot(NULL,0,DS(0,0)), + m_residual(NULL,0,DS(0,0)), enabled(true) {}; + + Equation m_eq; + typename Kernel::VectorMap m_diff_first, m_diff_first_rot; //first geometry diff + typename Kernel::VectorMap m_diff_second, m_diff_second_rot; //second geometry diff + typename Kernel::VectorMap m_residual; + + bool enabled; + AccessType access; + + typedef Equation eq_type; + }; + + struct placeholder { + virtual ~placeholder() {} + virtual placeholder* resetConstraint(geom_ptr first, geom_ptr second) const = 0; + virtual void calculate(geom_ptr first, geom_ptr second, Scalar scale, AccessType access = general) = 0; + virtual void treatLGZ(geom_ptr first, geom_ptr second) = 0; + virtual int equationCount() = 0; + virtual void setMaps(MES& mes, geom_ptr first, geom_ptr second) = 0; + virtual void collectPseudoPoints(geom_ptr first, geom_ptr second, Vec& vec1, Vec& vec2) = 0; + virtual void disable() = 0; + virtual placeholder* clone() = 0; + + //some runtime type infos are needed, as we cant access the contents with arbitrary functors + virtual std::vector getGenericEquations() = 0; + virtual std::vector getGenericConstraints() = 0; + virtual std::vector getEquationTypes() = 0; + virtual std::vector getConstraintTypes() = 0; + }; + int value; + +public: + template< typename ConstraintVector, typename tag1, typename tag2> + struct holder : public placeholder { + + //transform the constraints into eqautions with the now known types + typedef typename mpl::fold< ConstraintVector, mpl::vector<>, + mpl::push_back > >::type EquationVector; + + //create a vector of EquationSets with some mpl trickery + typedef typename mpl::fold< EquationVector, mpl::vector<>, + mpl::push_back > >::type eq_set_vector; + typedef typename fusion::result_of::as_vector::type EquationSets; + + typedef ConstraintVector Objects; + + template + struct has_option { + //we get the index of the eqaution in the eqaution vector, and as it is the same + //as the index of the constraint in the constraint vector we can extract the + //option type and check if it is no_option + typedef typename mpl::find::type iterator; + typedef typename mpl::distance::type, iterator>::type distance; + BOOST_MPL_ASSERT((mpl::not_::type > >)); + typedef typename fusion::result_of::at::type option_type; + typedef mpl::not_ > type; + }; + + struct OptionSetter { + + Objects& objects; + + OptionSetter(Objects& val); + + //only set the value if the equation has a option + template< typename T > + typename boost::enable_if::type, void>::type + operator()(EquationSet& val) const; + //if the equation has no otpion we do nothing! + template< typename T > + typename boost::enable_if::type>, void>::type + operator()(EquationSet& val) const; + }; + + struct Calculater { + + geom_ptr first, second; + Scalar scale; + AccessType access; + + Calculater(geom_ptr f, geom_ptr s, Scalar sc, AccessType a = general); + + template< typename T > + void operator()(T& val) const; + }; + + struct MapSetter { + MES& mes; + geom_ptr first, second; + + MapSetter(MES& m, geom_ptr f, geom_ptr s); + + template< typename T > + void operator()(T& val) const; + }; + + struct PseudoCollector { + Vec& points1; + Vec& points2; + geom_ptr first,second; + + PseudoCollector(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2); + + template< typename T > + void operator()(T& val) const; + }; + + struct LGZ { + geom_ptr first,second; + + LGZ(geom_ptr f, geom_ptr s); + + template< typename T > + void operator()(T& val) const; + }; + + + struct EquationCounter { + int& count; + + EquationCounter(int& c) : count(c) {}; + + template< typename T > + void operator()(T& val) const { + if(val.enabled) + count++; + }; + }; + + //workaround until we have a better analyser class + struct disabler { + template + void operator()(T& val) const { + val.enabled = false; + }; + }; + + struct GenericEquations { + std::vector& vec; + GenericEquations(std::vector& v); + + template + void operator()(T& val) const; + }; + + struct GenericConstraints { + std::vector& vec; + GenericConstraints(std::vector& v); + + template + void operator()(T& val) const; + }; + + struct Types { + std::vector& vec; + Types(std::vector& v); + + template + void operator()(T& val) const; + }; + + + holder(Objects& obj); + + virtual void calculate(geom_ptr first, geom_ptr second, Scalar scale, AccessType a = general); + virtual void treatLGZ(geom_ptr first, geom_ptr second); + virtual placeholder* resetConstraint(geom_ptr first, geom_ptr second) const; + virtual void setMaps(MES& mes, geom_ptr first, geom_ptr second); + virtual void collectPseudoPoints(geom_ptr f, geom_ptr s, Vec& vec1, Vec& vec2); + virtual placeholder* clone(); + virtual int equationCount(); + virtual void disable(); + + virtual std::vector getGenericEquations(); + virtual std::vector getGenericConstraints(); + virtual std::vector getEquationTypes(); + virtual std::vector getConstraintTypes(); + + EquationSets m_sets; + Objects m_objects; + protected: + void for_each(EquationSets m_sets, Calculater Calculater); + }; + + placeholder* content; + Connection cf, cs; +public: + geom_ptr first, second; +}; + +};//detail +};//dcm + +#ifndef DCM_EXTERNAL_CORE +#include "imp/constraint_imp.hpp" +#include "imp/constraint_holder_imp.hpp" +#endif + +#endif //GCM_CONSTRAINT_H + + + diff --git a/src/Mod/Assembly/App/opendcm/core/defines.hpp b/src/Mod/Assembly/App/opendcm/core/defines.hpp new file mode 100644 index 000000000..b6547533b --- /dev/null +++ b/src/Mod/Assembly/App/opendcm/core/defines.hpp @@ -0,0 +1,41 @@ +/* + openDCM, dimensional constraint manager + Copyright (C) 2013 Stefan Troeger + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef GCM_DEFINES_CORE_H +#define GCM_DEFINES_CORE_H + + +#include +#include + +namespace dcm { + +//all solving related errors +typedef boost::error_info error_message; +typedef boost::error_info error_type_first_geometry; +typedef boost::error_info error_type_second_geometry; + +//exception codes are needed by the user +struct creation_error : virtual boost::exception {}; +struct solving_error : virtual boost::exception {}; +struct constraint_error : virtual boost::exception {}; + +} //dcm + +#endif //GCM_DEFINES_CORE_H \ No newline at end of file diff --git a/src/Mod/Assembly/App/opendcm/core/equations.hpp b/src/Mod/Assembly/App/opendcm/core/equations.hpp new file mode 100644 index 000000000..795834e10 --- /dev/null +++ b/src/Mod/Assembly/App/opendcm/core/equations.hpp @@ -0,0 +1,422 @@ +/* + openDCM, dimensional constraint manager + Copyright (C) 2012 Stefan Troeger + + This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more detemplate tails. + + You should have received a copy of the GNU Lesser General Public License along + with this library; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef DCM_EQUATIONS_H +#define DCM_EQUATIONS_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace fusion = boost::fusion; +namespace mpl = boost::mpl; + +#include "kernel.hpp" + +namespace dcm { + +//the possible directions +enum Direction { parallel, equal, opposite, perpendicular }; + +//the possible solution spaces +enum SolutionSpace {bidirectional, positiv_directional, negative_directional}; + +struct no_option {}; + +template +struct Pseudo { + typedef std::vector > Vec; + + template + void calculatePseudo(const E::MatrixBase& param1, Vec& v1, const E::MatrixBase& param2, Vec& v2) {}; +}; + +template +struct Scale { + void setScale(typename Kernel::number_type scale) {}; +}; + +template +struct PseudoScale { + typedef std::vector > Vec; + + template + void calculatePseudo(const E::MatrixBase& param1, Vec& v1, const E::MatrixBase& param2, Vec& v2) {}; + void setScale(typename Kernel::number_type scale) {}; +}; + +//type to allow a metaprogramming check for a Equation +struct EQ {}; + +//template +//struct pushed_seq; + +//metafunctions to retrieve the options of an equation +template +struct options { + typedef typename T::options type; +}; +template<> +struct options< mpl::arg<-1> > { + typedef fusion::map<> type; +}; +template +struct has_option : public mpl::if_::type, Opt>, boost::true_type, boost::false_type>::type { + typedef typename mpl::has_key::type, Opt>::type type; +}; +template +struct seq_has_option { + typedef typename mpl::transform >::type bool_seq; + typedef typename mpl::not_::type, mpl::end > >::type type; +}; + +template +struct constraint_sequence : public seq { + + template + void pretty(T type) { + std::cout<<"pretty: "<<__PRETTY_FUNCTION__< + typename boost::enable_if< boost::is_base_of< dcm::EQ, T>, typename pushed_seq::type >::type operator &(T& val); + + //an sequence gets added to this sequence (happens only if sequenced equations like coincident are used) + template + typename boost::enable_if< mpl::is_sequence, typename pushed_seq::type >::type operator &(T& val); + */ + //we also allow to set values directly into the equation, as this makes it more compftable for multi constraints + //as align. Note that this only works if all option types of all equations in this sequence are distinguishable + template + typename boost::enable_if::type, Derived&>::type + operator=(const T& val) { + + fusion::filter_view > view(*this); + fusion::front(view) = val; + return *((Derived*)this); + }; + +}; + +/* +template +struct get_equation_id { + typedef typename T::ID type; +}; + +template +struct pushed_seq { + typedef typename mpl::if_, Seq, fusion::vector1 >::type S1; + typedef typename mpl::if_, T, fusion::vector1 >::type S2; + + typedef typename mpl::fold< S2, S1, mpl::if_< boost::is_same< + mpl::find, mpl::end >, mpl::push_back, mpl::_1> >::type unique_vector; + typedef typename mpl::sort, get_equation_id > >::type sorted_vector; + + typedef typename fusion::result_of::as_vector< sorted_vector >::type vec; + typedef constraint_sequence type; +};*/ + +template +struct Equation : public EQ { + + typedef typename mpl::if_, Option, mpl::vector