Optimize intermediate nodes cut normal.

Before this commit, the cut normal of intermediate nodes doesn't consider the original nodes' travesal direction. This will cause self intersection in some cases.
master
Jeremy Hu 2019-07-07 20:25:42 +09:30
parent eb91a8a16c
commit 8d315e3c64
7 changed files with 164 additions and 119 deletions

View File

@ -1,119 +1,117 @@
DUST3D 1.0 xml 0000000193 DUST3D 1.0 xml 0000000193
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ds3> <ds3>
<model name="model.xml" offset="0" size="18427"/> <model name="model.xml" offset="0" size="18064"/>
<asset name="canvas.png" offset="18427" size="163519"/> <asset name="canvas.png" offset="18064" size="163519"/>
</ds3> </ds3>
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<canvas originX="0.832218" originY="0.430706" originZ="2.51087" rigType="None"> <canvas originX="0.832218" originY="0.430706" originZ="2.51087" rigType="None">
<nodes> <nodes>
<node id="{00fde052-9d4e-448e-9682-f5ed93434e0c}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" radius="0.0182927" x="0.872962" y="0.178297" z="2.375"/> <node id="{00fde052-9d4e-448e-9682-f5ed93434e0c}" partId="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" radius="0.0182927" x="0.872962" y="0.178297" z="2.375"/>
<node id="{091f00c6-a346-44ce-b2f0-905256644b35}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" radius="0.0108696" x="1.00543" y="0.407609" z="2.1875"/> <node id="{091f00c6-a346-44ce-b2f0-905256644b35}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" radius="0.0108696" x="1.00543" y="0.407609" z="2.1875"/>
<node id="{1021605a-1c1a-4266-83bb-761abfcaebd4}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" radius="0.0353261" x="0.88587" y="0.278897" z="2.30844"/> <node id="{1021605a-1c1a-4266-83bb-761abfcaebd4}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" radius="0.0353261" x="0.88587" y="0.278897" z="2.30844"/>
<node id="{18e00014-6fd3-4f46-b474-25a98ad0a5a5}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0271739" x="0.831522" y="0.524457" z="2.98098"/> <node id="{18e00014-6fd3-4f46-b474-25a98ad0a5a5}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0271739" x="0.831522" y="0.524457" z="2.98098"/>
<node id="{1ef138ab-f1c0-416c-af05-b988dc62c9ec}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0597826" x="0.831522" y="0.475543" z="2.91848"/> <node id="{1ef138ab-f1c0-416c-af05-b988dc62c9ec}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0597826" x="0.831522" y="0.475543" z="2.91848"/>
<node id="{3ccfd176-17d3-4e5e-9a66-7973b67a9b7d}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.076087" x="0.831522" y="0.290761" z="2.4375"/> <node id="{3ccfd176-17d3-4e5e-9a66-7973b67a9b7d}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.076087" x="0.831522" y="0.290761" z="2.4375"/>
<node id="{45fa4407-c043-4aba-907d-4c84d16ba5e5}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" radius="0.0108696" x="1.00543" y="0.665761" z="2.13587"/> <node id="{45fa4407-c043-4aba-907d-4c84d16ba5e5}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" radius="0.0108696" x="1.00543" y="0.665761" z="2.13587"/>
<node id="{4fc24460-bb11-492b-95d5-3df726947c9a}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0466936" x="0.831522" y="0.228261" z="2.2962"/> <node id="{4fc24460-bb11-492b-95d5-3df726947c9a}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0466936" x="0.831522" y="0.228261" z="2.2962"/>
<node id="{59f24f88-0441-418f-8d8d-4d30d4b5015b}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" radius="0.0108696" x="1.28533" y="0.741848" z="2.86141"/> <node id="{59f24f88-0441-418f-8d8d-4d30d4b5015b}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" radius="0.0108696" x="1.28533" y="0.741848" z="2.86141"/>
<node id="{5c63c4df-8f54-4fef-933a-f975973d0e0e}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" radius="0.0127174" x="1.07609" y="0.75" z="2.66033"/> <node id="{5c63c4df-8f54-4fef-933a-f975973d0e0e}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" radius="0.0127174" x="1.07609" y="0.75" z="2.66033"/>
<node id="{60de62dd-338e-425a-9b83-ed0776bb380a}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0163044" x="0.831522" y="0.274457" z="2.11617"/> <node id="{60de62dd-338e-425a-9b83-ed0776bb380a}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0163044" x="0.831522" y="0.274457" z="2.11617"/>
<node id="{67ed5a94-e749-46d1-8ccf-2b33a3e878d6}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0244565" x="0.831522" y="0.345109" z="2.19293"/> <node id="{67ed5a94-e749-46d1-8ccf-2b33a3e878d6}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0244565" x="0.831522" y="0.345109" z="2.19293"/>
<node id="{6a47f6ac-e4a8-4e5d-9000-b4c0dfb999a3}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0625" x="0.831522" y="0.315217" z="2.50815"/> <node id="{6a47f6ac-e4a8-4e5d-9000-b4c0dfb999a3}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0625" x="0.831522" y="0.315217" z="2.50815"/>
<node id="{6e2cde74-aba5-477a-8677-5209f03f021f}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" radius="0.0213415" x="0.864193" y="0.232555" z="2.39024"/> <node id="{71b0f00a-6909-4121-bf1d-83b0a64eab41}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" radius="0.0127174" x="1.21196" y="0.866848" z="2.78261"/>
<node id="{71b0f00a-6909-4121-bf1d-83b0a64eab41}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" radius="0.0127174" x="1.21196" y="0.866848" z="2.78261"/> <node id="{71ff2d8c-862c-4b06-aa8e-6d89afc335fd}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0244565" x="0.831522" y="0.277174" z="2.2337"/>
<node id="{71ff2d8c-862c-4b06-aa8e-6d89afc335fd}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0244565" x="0.831522" y="0.277174" z="2.2337"/> <node id="{83aaf66e-e525-42d1-b8fe-3f1772fe57ef}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" radius="0.0190217" x="0.869565" y="0.293478" z="2.43839"/>
<node id="{83aaf66e-e525-42d1-b8fe-3f1772fe57ef}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" radius="0.0190217" x="0.869565" y="0.293478" z="2.43839"/> <node id="{8aaa9417-0abe-4616-9ef3-01de9803cfe2}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" radius="0.0190217" x="1.13859" y="0.38587" z="2.46624"/>
<node id="{8aaa9417-0abe-4616-9ef3-01de9803cfe2}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" radius="0.0190217" x="1.13859" y="0.38587" z="2.46624"/> <node id="{8e680f16-9603-40de-9a5e-90a849ff05f6}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" radius="0.0344565" x="0.872282" y="0.260869" z="2.37976"/>
<node id="{8e680f16-9603-40de-9a5e-90a849ff05f6}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" radius="0.0344565" x="0.872282" y="0.260869" z="2.37976"/> <node id="{95b3fc4e-9bab-4b12-80c0-a875649ca4aa}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" radius="0.0108696" x="1.16033" y="0.842391" z="2.01087"/>
<node id="{95b3fc4e-9bab-4b12-80c0-a875649ca4aa}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" radius="0.0108696" x="1.16033" y="0.842391" z="2.01087"/> <node id="{96f55ae2-c07f-4637-b8b6-4b7d4c2b209a}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0438766" x="0.831522" y="0.271739" z="2.17935"/>
<node id="{96f55ae2-c07f-4637-b8b6-4b7d4c2b209a}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0438766" x="0.831522" y="0.271739" z="2.17935"/> <node id="{98a8ed94-50ed-43d3-85cf-7968f5e260da}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" radius="0.0108696" x="0.980978" y="0.453804" z="2.78533"/>
<node id="{98a8ed94-50ed-43d3-85cf-7968f5e260da}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" radius="0.0108696" x="0.980978" y="0.453804" z="2.78533"/> <node id="{9b835bb3-040c-4f5f-9993-4240128e0297}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" radius="0.0222283" x="0.948369" y="0.349185" z="2.39368"/>
<node id="{9b835bb3-040c-4f5f-9993-4240128e0297}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" radius="0.0222283" x="0.948369" y="0.349185" z="2.39368"/> <node id="{a0e15099-f840-47fe-b7cc-76e2821f82c8}" partId="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" radius="0.0689289" x="0.916609" y="0.236665" z="2.64057"/>
<node id="{a0e15099-f840-47fe-b7cc-76e2821f82c8}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" radius="0.0689289" x="0.916609" y="0.236665" z="2.64057"/> <node id="{a64dcc04-41eb-4d71-b95a-9fb7dacc3350}" partId="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" radius="0.0271739" x="0.870884" y="0.198072" z="2.41031"/>
<node id="{a64dcc04-41eb-4d71-b95a-9fb7dacc3350}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" radius="0.0271739" x="0.870884" y="0.198072" z="2.41031"/> <node id="{abfebd7d-3a35-41c8-adee-06aced895298}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" radius="0.0108696" x="1.1087" y="0.774457" z="2.06793"/>
<node id="{abfebd7d-3a35-41c8-adee-06aced895298}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" radius="0.0108696" x="1.1087" y="0.774457" z="2.06793"/> <node id="{ac99b0c2-942c-446e-a0bf-7210382e66a5}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0108696" x="0.831522" y="0.5625" z="2.21467"/>
<node id="{ac99b0c2-942c-446e-a0bf-7210382e66a5}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0108696" x="0.831522" y="0.5625" z="2.21467"/> <node id="{b0c0ad56-ba00-4999-8adb-466c6d7185ba}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0597826" x="0.831522" y="0.32337" z="2.61141"/>
<node id="{b0c0ad56-ba00-4999-8adb-466c6d7185ba}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0597826" x="0.831522" y="0.32337" z="2.61141"/> <node id="{bfb2b58d-773e-4636-a95f-f036139f6d9b}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0108696" x="0.831522" y="0.244565" z="2.04348"/>
<node id="{bfb2b58d-773e-4636-a95f-f036139f6d9b}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0108696" x="0.831522" y="0.244565" z="2.04348"/> <node id="{cc6c7d03-156f-455f-8456-0b6438e1f6ef}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" radius="0.0108696" x="1.1875" y="0.869565" z="1.94293"/>
<node id="{cc6c7d03-156f-455f-8456-0b6438e1f6ef}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" radius="0.0108696" x="1.1875" y="0.869565" z="1.94293"/> <node id="{d45a860c-f9ec-41bb-868e-3bdc3cf04e8d}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0190217" x="0.831522" y="0.445652" z="2.20109"/>
<node id="{d45a860c-f9ec-41bb-868e-3bdc3cf04e8d}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0190217" x="0.831522" y="0.445652" z="2.20109"/> <node id="{d6d1a24b-f3b8-478d-9989-feda57a2ee32}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0108696" x="0.831522" y="0.263587" z="2.0788"/>
<node id="{d6d1a24b-f3b8-478d-9989-feda57a2ee32}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0108696" x="0.831522" y="0.263587" z="2.0788"/> <node id="{dacc2607-14f6-4c36-a20a-31d5b57d1488}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0597826" x="0.831522" y="0.350543" z="2.73098"/>
<node id="{dacc2607-14f6-4c36-a20a-31d5b57d1488}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0597826" x="0.831522" y="0.350543" z="2.73098"/> <node id="{deb5ae03-03f6-4e0c-a275-fa681b60b379}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" radius="0.0127174" x="1.23098" y="0.899456" z="2.85055"/>
<node id="{deb5ae03-03f6-4e0c-a275-fa681b60b379}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" radius="0.0127174" x="1.23098" y="0.899456" z="2.85055"/> <node id="{df279fce-55a5-4c68-bb96-feefc9a068c8}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" radius="0.0127174" x="0.972826" y="0.538044" z="2.55163"/>
<node id="{df279fce-55a5-4c68-bb96-feefc9a068c8}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" radius="0.0127174" x="0.972826" y="0.538044" z="2.55163"/> <node id="{e1fa1f4c-8426-4dc1-afc1-3f8dee8f1641}" partId="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" radius="0.107635" x="0.940221" y="0.304323" z="2.8689"/>
<node id="{e1fa1f4c-8426-4dc1-afc1-3f8dee8f1641}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" radius="0.107635" x="0.940221" y="0.304323" z="2.8689"/> <node id="{e9410d86-9d17-41a5-9b55-8587d1e93ea3}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" radius="0.0108696" x="1.45652" y="0.913043" z="3.05163"/>
<node id="{e9410d86-9d17-41a5-9b55-8587d1e93ea3}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" radius="0.0108696" x="1.45652" y="0.913043" z="3.05163"/> <node id="{e9d3ac47-6d17-4439-8176-9c51498f8cf0}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" radius="0.0108696" x="1.01359" y="0.470109" z="2.50428"/>
<node id="{e9d3ac47-6d17-4439-8176-9c51498f8cf0}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" radius="0.0108696" x="1.01359" y="0.470109" z="2.50428"/> <node id="{f1a99c28-4dd0-45f5-9dc4-769ff13d2fda}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" radius="0.0190217" x="1.01359" y="0.413043" z="2.35598"/>
<node id="{f1a99c28-4dd0-45f5-9dc4-769ff13d2fda}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" radius="0.0190217" x="1.01359" y="0.413043" z="2.35598"/> <node id="{f2677136-fe7c-4157-bf6e-01f0f51ef4ff}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0597826" x="0.831522" y="0.407609" z="2.84239"/>
<node id="{f2677136-fe7c-4157-bf6e-01f0f51ef4ff}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0597826" x="0.831522" y="0.407609" z="2.84239"/> <node id="{f5447f26-5f45-4192-97a8-0d6cc635a19b}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" radius="0.0108696" x="1.5" y="0.9375" z="3.11685"/>
<node id="{f5447f26-5f45-4192-97a8-0d6cc635a19b}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" radius="0.0108696" x="1.5" y="0.9375" z="3.11685"/> <node id="{f6045c8a-b651-425b-86d6-4656ed9d9081}" partId="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" radius="0.0597826" x="1.01505" y="0.370967" z="3.06827"/>
<node id="{f6045c8a-b651-425b-86d6-4656ed9d9081}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" radius="0.0597826" x="1.01505" y="0.370967" z="3.06827"/> <node id="{f845abe2-f311-47be-8c61-8b0fa1fa98d2}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" radius="0.0108696" x="1.40761" y="0.858696" z="2.96467"/>
<node id="{f845abe2-f311-47be-8c61-8b0fa1fa98d2}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" radius="0.0108696" x="1.40761" y="0.858696" z="2.96467"/> <node id="{f9dad8ee-47b7-4fb4-aa7a-846995320792}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" radius="0.0682336" x="0.831522" y="0.214674" z="2.37228"/>
<node id="{f9dad8ee-47b7-4fb4-aa7a-846995320792}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" radius="0.0682336" x="0.831522" y="0.214674" z="2.37228"/> <node id="{fa1a535e-4d99-42a8-930c-2143b1d124eb}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" radius="0.0217391" x="1.02717" y="0.342391" z="2.32065"/>
<node id="{fa1a535e-4d99-42a8-930c-2143b1d124eb}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" radius="0.0217391" x="1.02717" y="0.342391" z="2.32065"/> <node id="{fb6417cf-c962-41fd-ac81-20e8b427ab2e}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" radius="0.01" x="1.17391" y="0.826087" z="2.72283"/>
<node id="{fb6417cf-c962-41fd-ac81-20e8b427ab2e}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" radius="0.01" x="1.17391" y="0.826087" z="2.72283"/> <node id="{fd9f1818-8101-4850-a420-55f72567c639}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" radius="0.0127174" x="1.02174" y="0.470109" z="2.44022"/>
<node id="{fd9f1818-8101-4850-a420-55f72567c639}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" radius="0.0127174" x="1.02174" y="0.470109" z="2.44022"/> <node id="{fdfccd5b-e3a1-4ed3-8e26-2db335c6b683}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" radius="0.0317391" x="1.1087" y="0.380435" z="2.40761"/>
<node id="{fdfccd5b-e3a1-4ed3-8e26-2db335c6b683}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" radius="0.0317391" x="1.1087" y="0.380435" z="2.40761"/>
</nodes> </nodes>
<edges> <edges>
<edge from="{60de62dd-338e-425a-9b83-ed0776bb380a}" id="{004e3284-50b1-4c43-ae03-351057f72d34}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{d6d1a24b-f3b8-478d-9989-feda57a2ee32}"/> <edge from="{60de62dd-338e-425a-9b83-ed0776bb380a}" id="{004e3284-50b1-4c43-ae03-351057f72d34}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{d6d1a24b-f3b8-478d-9989-feda57a2ee32}"/>
<edge from="{1021605a-1c1a-4266-83bb-761abfcaebd4}" id="{0569f362-f47c-485c-a6a9-6e3481b21a90}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" to="{fa1a535e-4d99-42a8-930c-2143b1d124eb}"/> <edge from="{1021605a-1c1a-4266-83bb-761abfcaebd4}" id="{0569f362-f47c-485c-a6a9-6e3481b21a90}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" to="{fa1a535e-4d99-42a8-930c-2143b1d124eb}"/>
<edge from="{f1a99c28-4dd0-45f5-9dc4-769ff13d2fda}" id="{0a8be92c-5977-4471-b2d3-5009eda7df2e}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" to="{091f00c6-a346-44ce-b2f0-905256644b35}"/> <edge from="{f1a99c28-4dd0-45f5-9dc4-769ff13d2fda}" id="{0a8be92c-5977-4471-b2d3-5009eda7df2e}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" to="{091f00c6-a346-44ce-b2f0-905256644b35}"/>
<edge from="{5c63c4df-8f54-4fef-933a-f975973d0e0e}" id="{0b30676d-4c10-4c4b-aa73-04a7a42a1b7f}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" to="{fb6417cf-c962-41fd-ac81-20e8b427ab2e}"/> <edge from="{5c63c4df-8f54-4fef-933a-f975973d0e0e}" id="{0b30676d-4c10-4c4b-aa73-04a7a42a1b7f}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" to="{fb6417cf-c962-41fd-ac81-20e8b427ab2e}"/>
<edge from="{df279fce-55a5-4c68-bb96-feefc9a068c8}" id="{0b6366a7-a16e-4f6f-a0f7-13d1dfa5f591}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" to="{5c63c4df-8f54-4fef-933a-f975973d0e0e}"/> <edge from="{df279fce-55a5-4c68-bb96-feefc9a068c8}" id="{0b6366a7-a16e-4f6f-a0f7-13d1dfa5f591}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" to="{5c63c4df-8f54-4fef-933a-f975973d0e0e}"/>
<edge from="{b0c0ad56-ba00-4999-8adb-466c6d7185ba}" id="{0d2b5542-fbb8-4aa9-a0cb-c2517dcf1aa9}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{dacc2607-14f6-4c36-a20a-31d5b57d1488}"/> <edge from="{b0c0ad56-ba00-4999-8adb-466c6d7185ba}" id="{0d2b5542-fbb8-4aa9-a0cb-c2517dcf1aa9}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{dacc2607-14f6-4c36-a20a-31d5b57d1488}"/>
<edge from="{96f55ae2-c07f-4637-b8b6-4b7d4c2b209a}" id="{0e321006-a9ad-4bd1-9429-80e9b4781c3e}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{71ff2d8c-862c-4b06-aa8e-6d89afc335fd}"/> <edge from="{96f55ae2-c07f-4637-b8b6-4b7d4c2b209a}" id="{0e321006-a9ad-4bd1-9429-80e9b4781c3e}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{71ff2d8c-862c-4b06-aa8e-6d89afc335fd}"/>
<edge from="{67ed5a94-e749-46d1-8ccf-2b33a3e878d6}" id="{10582139-843f-4591-bc63-1e9ae19c6d42}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{d45a860c-f9ec-41bb-868e-3bdc3cf04e8d}"/> <edge from="{67ed5a94-e749-46d1-8ccf-2b33a3e878d6}" id="{10582139-843f-4591-bc63-1e9ae19c6d42}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{d45a860c-f9ec-41bb-868e-3bdc3cf04e8d}"/>
<edge from="{96f55ae2-c07f-4637-b8b6-4b7d4c2b209a}" id="{1da07ccf-31ce-4c11-84c3-10248b56f366}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{67ed5a94-e749-46d1-8ccf-2b33a3e878d6}"/> <edge from="{96f55ae2-c07f-4637-b8b6-4b7d4c2b209a}" id="{1da07ccf-31ce-4c11-84c3-10248b56f366}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{67ed5a94-e749-46d1-8ccf-2b33a3e878d6}"/>
<edge from="{45fa4407-c043-4aba-907d-4c84d16ba5e5}" id="{22253314-b363-4698-a072-c0a5ba0ac000}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" to="{abfebd7d-3a35-41c8-adee-06aced895298}"/> <edge from="{45fa4407-c043-4aba-907d-4c84d16ba5e5}" id="{22253314-b363-4698-a072-c0a5ba0ac000}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" to="{abfebd7d-3a35-41c8-adee-06aced895298}"/>
<edge from="{f9dad8ee-47b7-4fb4-aa7a-846995320792}" id="{23fcdae1-af2b-4420-a761-63f3d0d203b4}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{3ccfd176-17d3-4e5e-9a66-7973b67a9b7d}"/> <edge from="{f9dad8ee-47b7-4fb4-aa7a-846995320792}" id="{23fcdae1-af2b-4420-a761-63f3d0d203b4}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{3ccfd176-17d3-4e5e-9a66-7973b67a9b7d}"/>
<edge from="{8aaa9417-0abe-4616-9ef3-01de9803cfe2}" id="{35fca7ae-1411-4125-a29d-c977e60c2026}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" to="{e9d3ac47-6d17-4439-8176-9c51498f8cf0}"/> <edge from="{8aaa9417-0abe-4616-9ef3-01de9803cfe2}" id="{35fca7ae-1411-4125-a29d-c977e60c2026}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" to="{e9d3ac47-6d17-4439-8176-9c51498f8cf0}"/>
<edge from="{fdfccd5b-e3a1-4ed3-8e26-2db335c6b683}" id="{3a69636f-46a5-4363-88a3-afa75c303fb7}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" to="{fd9f1818-8101-4850-a420-55f72567c639}"/> <edge from="{fdfccd5b-e3a1-4ed3-8e26-2db335c6b683}" id="{3a69636f-46a5-4363-88a3-afa75c303fb7}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" to="{fd9f1818-8101-4850-a420-55f72567c639}"/>
<edge from="{f2677136-fe7c-4157-bf6e-01f0f51ef4ff}" id="{3af2982e-d86f-492c-b9e0-ef4f5c0af53d}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{1ef138ab-f1c0-416c-af05-b988dc62c9ec}"/> <edge from="{f2677136-fe7c-4157-bf6e-01f0f51ef4ff}" id="{3af2982e-d86f-492c-b9e0-ef4f5c0af53d}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{1ef138ab-f1c0-416c-af05-b988dc62c9ec}"/>
<edge from="{d45a860c-f9ec-41bb-868e-3bdc3cf04e8d}" id="{3d874434-2913-4166-8e6e-712a47e44db0}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{ac99b0c2-942c-446e-a0bf-7210382e66a5}"/> <edge from="{d45a860c-f9ec-41bb-868e-3bdc3cf04e8d}" id="{3d874434-2913-4166-8e6e-712a47e44db0}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{ac99b0c2-942c-446e-a0bf-7210382e66a5}"/>
<edge from="{f845abe2-f311-47be-8c61-8b0fa1fa98d2}" id="{4dfeb7b4-4426-418f-b85f-c14da4d296f2}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" to="{e9410d86-9d17-41a5-9b55-8587d1e93ea3}"/> <edge from="{f845abe2-f311-47be-8c61-8b0fa1fa98d2}" id="{4dfeb7b4-4426-418f-b85f-c14da4d296f2}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" to="{e9410d86-9d17-41a5-9b55-8587d1e93ea3}"/>
<edge from="{6a47f6ac-e4a8-4e5d-9000-b4c0dfb999a3}" id="{566cd759-190b-4374-b57d-1ef8ed54cb45}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{b0c0ad56-ba00-4999-8adb-466c6d7185ba}"/> <edge from="{6a47f6ac-e4a8-4e5d-9000-b4c0dfb999a3}" id="{566cd759-190b-4374-b57d-1ef8ed54cb45}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{b0c0ad56-ba00-4999-8adb-466c6d7185ba}"/>
<edge from="{dacc2607-14f6-4c36-a20a-31d5b57d1488}" id="{5b0805fc-6b71-4a8f-9318-4dd3df63f718}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{f2677136-fe7c-4157-bf6e-01f0f51ef4ff}"/> <edge from="{dacc2607-14f6-4c36-a20a-31d5b57d1488}" id="{5b0805fc-6b71-4a8f-9318-4dd3df63f718}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{f2677136-fe7c-4157-bf6e-01f0f51ef4ff}"/>
<edge from="{a64dcc04-41eb-4d71-b95a-9fb7dacc3350}" id="{63dac02d-b2f8-4ebc-98c4-54fcea0d9798}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" to="{00fde052-9d4e-448e-9682-f5ed93434e0c}"/> <edge from="{a64dcc04-41eb-4d71-b95a-9fb7dacc3350}" id="{63dac02d-b2f8-4ebc-98c4-54fcea0d9798}" partId="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" to="{00fde052-9d4e-448e-9682-f5ed93434e0c}"/>
<edge from="{a64dcc04-41eb-4d71-b95a-9fb7dacc3350}" id="{661816f3-9c26-42d5-a3db-7edd50ed8405}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" to="{6e2cde74-aba5-477a-8677-5209f03f021f}"/> <edge from="{60de62dd-338e-425a-9b83-ed0776bb380a}" id="{67bd7a5e-4002-418c-ad41-f8827056d936}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{96f55ae2-c07f-4637-b8b6-4b7d4c2b209a}"/>
<edge from="{60de62dd-338e-425a-9b83-ed0776bb380a}" id="{67bd7a5e-4002-418c-ad41-f8827056d936}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{96f55ae2-c07f-4637-b8b6-4b7d4c2b209a}"/> <edge from="{95b3fc4e-9bab-4b12-80c0-a875649ca4aa}" id="{67d3a132-f6f4-4c39-93fd-53d66a5df4ab}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" to="{cc6c7d03-156f-455f-8456-0b6438e1f6ef}"/>
<edge from="{95b3fc4e-9bab-4b12-80c0-a875649ca4aa}" id="{67d3a132-f6f4-4c39-93fd-53d66a5df4ab}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" to="{cc6c7d03-156f-455f-8456-0b6438e1f6ef}"/> <edge from="{a0e15099-f840-47fe-b7cc-76e2821f82c8}" id="{6cc8a10c-58e8-4833-98f3-d1bba4461f34}" partId="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" to="{e1fa1f4c-8426-4dc1-afc1-3f8dee8f1641}"/>
<edge from="{a0e15099-f840-47fe-b7cc-76e2821f82c8}" id="{6cc8a10c-58e8-4833-98f3-d1bba4461f34}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" to="{e1fa1f4c-8426-4dc1-afc1-3f8dee8f1641}"/> <edge from="{a64dcc04-41eb-4d71-b95a-9fb7dacc3350}" id="{720d02e7-45a3-4659-a779-2b775f58d61f}" partId="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" to="{a0e15099-f840-47fe-b7cc-76e2821f82c8}"/>
<edge from="{a64dcc04-41eb-4d71-b95a-9fb7dacc3350}" id="{720d02e7-45a3-4659-a779-2b775f58d61f}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" to="{a0e15099-f840-47fe-b7cc-76e2821f82c8}"/> <edge from="{e9410d86-9d17-41a5-9b55-8587d1e93ea3}" id="{748ecd4b-ecaa-4707-9d1b-eba56429b77a}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" to="{f5447f26-5f45-4192-97a8-0d6cc635a19b}"/>
<edge from="{e9410d86-9d17-41a5-9b55-8587d1e93ea3}" id="{748ecd4b-ecaa-4707-9d1b-eba56429b77a}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" to="{f5447f26-5f45-4192-97a8-0d6cc635a19b}"/> <edge from="{e1fa1f4c-8426-4dc1-afc1-3f8dee8f1641}" id="{76dd8ca8-896a-4899-acff-c60f42725d45}" partId="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" to="{f6045c8a-b651-425b-86d6-4656ed9d9081}"/>
<edge from="{e1fa1f4c-8426-4dc1-afc1-3f8dee8f1641}" id="{76dd8ca8-896a-4899-acff-c60f42725d45}" partId="{00240306-d240-46c1-9521-5c82417cf7e5}" to="{f6045c8a-b651-425b-86d6-4656ed9d9081}"/> <edge from="{091f00c6-a346-44ce-b2f0-905256644b35}" id="{7cd9de86-8db5-4672-9d73-e813f5cad9a9}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" to="{45fa4407-c043-4aba-907d-4c84d16ba5e5}"/>
<edge from="{091f00c6-a346-44ce-b2f0-905256644b35}" id="{7cd9de86-8db5-4672-9d73-e813f5cad9a9}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" to="{45fa4407-c043-4aba-907d-4c84d16ba5e5}"/> <edge from="{abfebd7d-3a35-41c8-adee-06aced895298}" id="{7de5e8e0-24ff-4b64-9047-4bd8f4855506}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" to="{95b3fc4e-9bab-4b12-80c0-a875649ca4aa}"/>
<edge from="{abfebd7d-3a35-41c8-adee-06aced895298}" id="{7de5e8e0-24ff-4b64-9047-4bd8f4855506}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" to="{95b3fc4e-9bab-4b12-80c0-a875649ca4aa}"/> <edge from="{8e680f16-9603-40de-9a5e-90a849ff05f6}" id="{8a744155-4a9f-446d-a39e-713fdd134426}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" to="{9b835bb3-040c-4f5f-9993-4240128e0297}"/>
<edge from="{8e680f16-9603-40de-9a5e-90a849ff05f6}" id="{8a744155-4a9f-446d-a39e-713fdd134426}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" to="{9b835bb3-040c-4f5f-9993-4240128e0297}"/> <edge from="{fa1a535e-4d99-42a8-930c-2143b1d124eb}" id="{a439f439-4dba-488b-b4ee-d38b19fc4fcf}" partId="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" to="{f1a99c28-4dd0-45f5-9dc4-769ff13d2fda}"/>
<edge from="{fa1a535e-4d99-42a8-930c-2143b1d124eb}" id="{a439f439-4dba-488b-b4ee-d38b19fc4fcf}" partId="{70013409-b531-4248-988c-744f9dbdb5b8}" to="{f1a99c28-4dd0-45f5-9dc4-769ff13d2fda}"/> <edge from="{fd9f1818-8101-4850-a420-55f72567c639}" id="{a6357a12-14ba-4dc4-846b-4be892746e6a}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" to="{df279fce-55a5-4c68-bb96-feefc9a068c8}"/>
<edge from="{fd9f1818-8101-4850-a420-55f72567c639}" id="{a6357a12-14ba-4dc4-846b-4be892746e6a}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" to="{df279fce-55a5-4c68-bb96-feefc9a068c8}"/> <edge from="{71ff2d8c-862c-4b06-aa8e-6d89afc335fd}" id="{ab708822-ad92-4977-b209-b1103a334e82}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{4fc24460-bb11-492b-95d5-3df726947c9a}"/>
<edge from="{71ff2d8c-862c-4b06-aa8e-6d89afc335fd}" id="{ab708822-ad92-4977-b209-b1103a334e82}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{4fc24460-bb11-492b-95d5-3df726947c9a}"/> <edge from="{1ef138ab-f1c0-416c-af05-b988dc62c9ec}" id="{b17d6b41-898c-46db-8d88-1117bc53c627}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{18e00014-6fd3-4f46-b474-25a98ad0a5a5}"/>
<edge from="{1ef138ab-f1c0-416c-af05-b988dc62c9ec}" id="{b17d6b41-898c-46db-8d88-1117bc53c627}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{18e00014-6fd3-4f46-b474-25a98ad0a5a5}"/> <edge from="{71b0f00a-6909-4121-bf1d-83b0a64eab41}" id="{c232a9eb-fda5-4938-82da-c807c021b102}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" to="{deb5ae03-03f6-4e0c-a275-fa681b60b379}"/>
<edge from="{71b0f00a-6909-4121-bf1d-83b0a64eab41}" id="{c232a9eb-fda5-4938-82da-c807c021b102}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" to="{deb5ae03-03f6-4e0c-a275-fa681b60b379}"/> <edge from="{9b835bb3-040c-4f5f-9993-4240128e0297}" id="{caaaf017-8034-4deb-ac06-b5052603bd6e}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" to="{fdfccd5b-e3a1-4ed3-8e26-2db335c6b683}"/>
<edge from="{9b835bb3-040c-4f5f-9993-4240128e0297}" id="{caaaf017-8034-4deb-ac06-b5052603bd6e}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" to="{fdfccd5b-e3a1-4ed3-8e26-2db335c6b683}"/> <edge from="{d6d1a24b-f3b8-478d-9989-feda57a2ee32}" id="{cb1c1ed1-eb5b-4622-b491-2b454836600b}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{bfb2b58d-773e-4636-a95f-f036139f6d9b}"/>
<edge from="{d6d1a24b-f3b8-478d-9989-feda57a2ee32}" id="{cb1c1ed1-eb5b-4622-b491-2b454836600b}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{bfb2b58d-773e-4636-a95f-f036139f6d9b}"/> <edge from="{83aaf66e-e525-42d1-b8fe-3f1772fe57ef}" id="{cb880891-b7e8-4592-ab80-fd165c70eccb}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" to="{8aaa9417-0abe-4616-9ef3-01de9803cfe2}"/>
<edge from="{83aaf66e-e525-42d1-b8fe-3f1772fe57ef}" id="{cb880891-b7e8-4592-ab80-fd165c70eccb}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" to="{8aaa9417-0abe-4616-9ef3-01de9803cfe2}"/> <edge from="{98a8ed94-50ed-43d3-85cf-7968f5e260da}" id="{d102fa2e-afb6-4f0c-910a-2952dea4781c}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" to="{59f24f88-0441-418f-8d8d-4d30d4b5015b}"/>
<edge from="{98a8ed94-50ed-43d3-85cf-7968f5e260da}" id="{d102fa2e-afb6-4f0c-910a-2952dea4781c}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" to="{59f24f88-0441-418f-8d8d-4d30d4b5015b}"/> <edge from="{e9d3ac47-6d17-4439-8176-9c51498f8cf0}" id="{d55b2dbc-4c3a-4c52-9c2c-16127e00a889}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" to="{98a8ed94-50ed-43d3-85cf-7968f5e260da}"/>
<edge from="{e9d3ac47-6d17-4439-8176-9c51498f8cf0}" id="{d55b2dbc-4c3a-4c52-9c2c-16127e00a889}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" to="{98a8ed94-50ed-43d3-85cf-7968f5e260da}"/> <edge from="{3ccfd176-17d3-4e5e-9a66-7973b67a9b7d}" id="{d89420d6-ffca-4dd4-a5b5-2ff9b8618b01}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{6a47f6ac-e4a8-4e5d-9000-b4c0dfb999a3}"/>
<edge from="{3ccfd176-17d3-4e5e-9a66-7973b67a9b7d}" id="{d89420d6-ffca-4dd4-a5b5-2ff9b8618b01}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{6a47f6ac-e4a8-4e5d-9000-b4c0dfb999a3}"/> <edge from="{59f24f88-0441-418f-8d8d-4d30d4b5015b}" id="{ee50292f-d21a-4ba6-8e31-d2f9fb577398}" partId="{83d793eb-655e-4970-9dbd-851f5021b55d}" to="{f845abe2-f311-47be-8c61-8b0fa1fa98d2}"/>
<edge from="{59f24f88-0441-418f-8d8d-4d30d4b5015b}" id="{ee50292f-d21a-4ba6-8e31-d2f9fb577398}" partId="{cccd1405-8bea-4102-b788-158c124673dd}" to="{f845abe2-f311-47be-8c61-8b0fa1fa98d2}"/> <edge from="{fb6417cf-c962-41fd-ac81-20e8b427ab2e}" id="{f1d56833-ff9a-44d7-a337-76eb68549678}" partId="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" to="{71b0f00a-6909-4121-bf1d-83b0a64eab41}"/>
<edge from="{fb6417cf-c962-41fd-ac81-20e8b427ab2e}" id="{f1d56833-ff9a-44d7-a337-76eb68549678}" partId="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" to="{71b0f00a-6909-4121-bf1d-83b0a64eab41}"/> <edge from="{4fc24460-bb11-492b-95d5-3df726947c9a}" id="{fc919b1d-e12b-42d0-a3af-fc36c8c78ef4}" partId="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" to="{f9dad8ee-47b7-4fb4-aa7a-846995320792}"/>
<edge from="{4fc24460-bb11-492b-95d5-3df726947c9a}" id="{fc919b1d-e12b-42d0-a3af-fc36c8c78ef4}" partId="{4752ca3c-88a2-4811-bc55-93e824987847}" to="{f9dad8ee-47b7-4fb4-aa7a-846995320792}"/>
</edges> </edges>
<parts> <parts>
<part chamfered="false" deformWidth="0.2" disabled="false" id="{00240306-d240-46c1-9521-5c82417cf7e5}" locked="false" rounded="true" subdived="false" visible="true" xMirrored="true"/> <part chamfered="false" disabled="false" id="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" locked="false" rounded="false" subdived="false" visible="true" xMirrored="true"/>
<part chamfered="false" disabled="false" id="{4752ca3c-88a2-4811-bc55-93e824987847}" locked="false" rounded="true" subdived="true" visible="true" xMirrored="false"/> <part chamfered="false" disabled="false" id="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" locked="false" rounded="true" subdived="true" visible="true" xMirrored="false"/>
<part chamfered="false" disabled="false" id="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" locked="false" rounded="false" subdived="true" visible="true" xMirrored="true"/> <part chamfered="false" disabled="false" id="{83d793eb-655e-4970-9dbd-851f5021b55d}" locked="false" rounded="false" subdived="false" visible="true" xMirrored="true"/>
<part chamfered="false" disabled="false" id="{70013409-b531-4248-988c-744f9dbdb5b8}" locked="false" rounded="false" subdived="false" visible="true" xMirrored="true"/> <part chamfered="false" deformWidth="0.2" disabled="false" id="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" locked="false" rounded="true" subdived="false" visible="true" xMirrored="true"/>
<part chamfered="false" disabled="false" id="{cccd1405-8bea-4102-b788-158c124673dd}" locked="false" rounded="false" subdived="false" visible="true" xMirrored="true"/> <part chamfered="false" disabled="false" id="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" locked="false" rounded="false" subdived="true" visible="true" xMirrored="true"/>
</parts> </parts>
<components> <components>
<component combineMode="Normal" expanded="false" id="{fffc7482-46b1-4dc5-b808-e8076df6dada}" linkData="{4752ca3c-88a2-4811-bc55-93e824987847}" linkDataType="partId"/> <component combineMode="Normal" expanded="false" id="{98581c52-bbd3-441a-b32c-15a808d6447d}" linkData="{3ed01f45-9d7b-4e48-acb0-c764d4a99d12}" linkDataType="partId"/>
<component combineMode="Normal" expanded="false" id="{a95343d2-086f-4763-982c-b6e0373889ba}" linkData="{70013409-b531-4248-988c-744f9dbdb5b8}" linkDataType="partId"/> <component combineMode="Normal" expanded="false" id="{722d1b48-fd05-49f7-9875-60d25acef4e7}" linkData="{30253fd3-a9db-4381-b66b-2d9d45e97a2c}" linkDataType="partId"/>
<component combineMode="Normal" expanded="false" id="{9efec0bf-e793-4686-b9c6-3c1fd088ded1}" linkData="{4dfb3a4b-530c-4a93-9748-e8040d2fd622}" linkDataType="partId"/> <component combineMode="Normal" expanded="false" id="{db036670-cc08-4d1a-a77d-802da916bca9}" linkData="{dac15f3a-d745-47d2-bb9a-4dc14a118ec9}" linkDataType="partId"/>
<component combineMode="Normal" expanded="false" id="{f8f43aae-7471-47fa-b2be-a9e84a6a0102}" linkData="{cccd1405-8bea-4102-b788-158c124673dd}" linkDataType="partId"/> <component combineMode="Normal" expanded="false" id="{0bd2a12b-fd08-4ef2-9bbb-4f2ac9824b4e}" linkData="{83d793eb-655e-4970-9dbd-851f5021b55d}" linkDataType="partId"/>
<component combineMode="Normal" expanded="false" id="{7cc744a2-2529-4849-ad05-0911a02b6233}" linkData="{00240306-d240-46c1-9521-5c82417cf7e5}" linkDataType="partId"/> <component combineMode="Normal" expanded="false" id="{3f951d42-6888-4599-9f54-9d5ac197a1da}" linkData="{d78572c0-aed7-4d86-b9fa-e8765168c13d}" linkDataType="partId"/>
</components> </components>
<materials/> <materials/>
<poses/> <poses/>

View File

@ -1248,10 +1248,13 @@ void Document::addFromSnapshot(const Snapshot &snapshot, bool fromPaste)
for (const auto &it: cutFaceLinkedIdModifyMap) { for (const auto &it: cutFaceLinkedIdModifyMap) {
SkeletonPart &part = partMap[it.first]; SkeletonPart &part = partMap[it.first];
auto findNewLinkedId = oldNewIdMap.find(it.second); auto findNewLinkedId = oldNewIdMap.find(it.second);
if (findNewLinkedId == oldNewIdMap.end()) if (oldNewIdMap.find(it.second) == oldNewIdMap.end()) {
part.setCutFaceLinkedId(QUuid()); if (partMap.find(it.second) == partMap.end()) {
else part.setCutFaceLinkedId(QUuid());
}
} else {
part.setCutFaceLinkedId(findNewLinkedId->second); part.setCutFaceLinkedId(findNewLinkedId->second);
}
} }
for (const auto &nodeKv: snapshot.nodes) { for (const auto &nodeKv: snapshot.nodes) {
if (nodeKv.second.find("radius") == nodeKv.second.end() || if (nodeKv.second.find("radius") == nodeKv.second.end() ||

View File

@ -494,8 +494,11 @@ nodemesh::Combiner::Mesh *MeshGenerator::combinePartMesh(const QString &partIdSt
} }
std::vector<size_t> builderNodeIndices; std::vector<size_t> builderNodeIndices;
for (const auto &node: modifier->nodes()) for (const auto &node: modifier->nodes()) {
builderNodeIndices.push_back(builder->addNode(node.position, node.radius, node.cutTemplate)); auto nodeIndex = builder->addNode(node.position, node.radius, node.cutTemplate);
builder->setNodeOriginInfo(nodeIndex, node.nearOriginNodeIndex, node.farOriginNodeIndex);
builderNodeIndices.push_back(nodeIndex);
}
for (const auto &edge: modifier->edges()) for (const auto &edge: modifier->edges())
builder->addEdge(edge.firstNodeIndex, edge.secondNodeIndex); builder->addEdge(edge.firstNodeIndex, edge.secondNodeIndex);
bool buildSucceed = builder->build(); bool buildSucceed = builder->build();

View File

@ -99,6 +99,11 @@ void Builder::prepareNode(size_t nodeIndex)
neighborPositions[i] = neighbor.position; neighborPositions[i] = neighbor.position;
neighborRadius[i] = neighbor.radius; neighborRadius[i] = neighbor.radius;
} }
if (node.edges.size() == 1) {
node.cutNormal = node.raysToNeibors[0];
} else if (node.edges.size() == 2) {
node.cutNormal = (node.raysToNeibors[0] - node.raysToNeibors[1]) * 0.5;
}
auto baseNormalResult = calculateBaseNormal(node.raysToNeibors, auto baseNormalResult = calculateBaseNormal(node.raysToNeibors,
neighborPositions, neighborPositions,
neighborRadius); neighborRadius);
@ -108,6 +113,13 @@ void Builder::prepareNode(size_t nodeIndex)
node.initialBaseNormal = revisedBaseNormalAcordingToCutNormal(node.initialBaseNormal, node.traverseDirection); node.initialBaseNormal = revisedBaseNormalAcordingToCutNormal(node.initialBaseNormal, node.traverseDirection);
} }
void Builder::setNodeOriginInfo(size_t nodeIndex, int nearOriginNodeIndex, int farOriginNodeIndex)
{
auto &node = m_nodes[nodeIndex];
node.nearOriginNodeIndex = nearOriginNodeIndex;
node.farOriginNodeIndex = farOriginNodeIndex;
}
void Builder::resolveBaseNormalRecursively(size_t nodeIndex) void Builder::resolveBaseNormalRecursively(size_t nodeIndex)
{ {
auto &node = m_nodes[nodeIndex]; auto &node = m_nodes[nodeIndex];
@ -438,7 +450,7 @@ bool Builder::generateCutsForNode(size_t nodeIndex)
size_t neighborsCount = node.edges.size(); size_t neighborsCount = node.edges.size();
//qDebug() << "Generate cuts for node" << nodeIndex << "with neighbor count" << neighborsCount; //qDebug() << "Generate cuts for node" << nodeIndex << "with neighbor count" << neighborsCount;
if (1 == neighborsCount) { if (1 == neighborsCount) {
const QVector3D &cutNormal = node.raysToNeibors[0]; QVector3D cutNormal = node.cutNormal;
std::vector<QVector3D> cut; std::vector<QVector3D> cut;
makeCut(node.position, node.radius, node.cutTemplate, node.baseNormal, cutNormal, node.traverseDirection, cut, &node.cutFaceTransform); makeCut(node.position, node.radius, node.cutTemplate, node.baseNormal, cutNormal, node.traverseDirection, cut, &node.cutFaceTransform);
node.hasAdjustableCutFace = true; node.hasAdjustableCutFace = true;
@ -447,7 +459,23 @@ bool Builder::generateCutsForNode(size_t nodeIndex)
m_generatedFaces.push_back(vertices); m_generatedFaces.push_back(vertices);
m_edges[node.edges[0]].cuts.push_back({vertices, -cutNormal}); m_edges[node.edges[0]].cuts.push_back({vertices, -cutNormal});
} else if (2 == neighborsCount) { } else if (2 == neighborsCount) {
const QVector3D cutNormal = (node.raysToNeibors[0].normalized() - node.raysToNeibors[1].normalized()) / 2; QVector3D cutNormal = node.cutNormal;
if (-1 != node.nearOriginNodeIndex && -1 != node.farOriginNodeIndex) {
const auto &nearOriginNode = m_nodes[node.nearOriginNodeIndex];
const auto &farOriginNode = m_nodes[node.farOriginNodeIndex];
if (nearOriginNode.edges.size() <= 2 && farOriginNode.edges.size() <= 2) {
float nearDistance = node.position.distanceToPoint(nearOriginNode.position);
float farDistance = node.position.distanceToPoint(farOriginNode.position);
float totalDistance = nearDistance + farDistance;
float distanceFactor = nearDistance / totalDistance;
if (QVector3D::dotProduct(nearOriginNode.cutNormal, farOriginNode.cutNormal) <= 0)
cutNormal = (nearOriginNode.cutNormal * (1.0 - distanceFactor) - farOriginNode.cutNormal * distanceFactor).normalized();
else
cutNormal = (nearOriginNode.cutNormal * (1.0 - distanceFactor) + farOriginNode.cutNormal * distanceFactor).normalized();
if (QVector3D::dotProduct(cutNormal, node.cutNormal) <= 0)
cutNormal = -cutNormal;
}
}
std::vector<QVector3D> cut; std::vector<QVector3D> cut;
makeCut(node.position, node.radius, node.cutTemplate, node.baseNormal, cutNormal, node.traverseDirection, cut, &node.cutFaceTransform); makeCut(node.position, node.radius, node.cutTemplate, node.baseNormal, cutNormal, node.traverseDirection, cut, &node.cutFaceTransform);
node.hasAdjustableCutFace = true; node.hasAdjustableCutFace = true;
@ -688,26 +716,25 @@ void Builder::makeCut(const QVector3D &position,
float radius, float radius,
const std::vector<QVector2D> &cutTemplate, const std::vector<QVector2D> &cutTemplate,
QVector3D &baseNormal, QVector3D &baseNormal,
const QVector3D &cutNormal, QVector3D &cutNormal,
const QVector3D &traverseDirection, const QVector3D &traverseDirection,
std::vector<QVector3D> &resultCut, std::vector<QVector3D> &resultCut,
CutFaceTransform *cutFaceTransform) CutFaceTransform *cutFaceTransform)
{ {
auto finalCutTemplate = cutTemplate; auto finalCutTemplate = cutTemplate;
auto finalCutNormal = cutNormal;
float degree = 0; float degree = 0;
if (!qFuzzyIsNull(m_cutRotation)) { if (!qFuzzyIsNull(m_cutRotation)) {
degree = m_cutRotation * 180; degree = m_cutRotation * 180;
} }
if (QVector3D::dotProduct(cutNormal, traverseDirection) <= 0) { if (QVector3D::dotProduct(cutNormal, traverseDirection) <= 0) {
finalCutNormal = -finalCutNormal; cutNormal = -cutNormal;
std::reverse(finalCutTemplate.begin(), finalCutTemplate.end()); std::reverse(finalCutTemplate.begin(), finalCutTemplate.end());
std::rotate(finalCutTemplate.begin(), finalCutTemplate.begin() + finalCutTemplate.size() - 1, finalCutTemplate.end()); std::rotate(finalCutTemplate.begin(), finalCutTemplate.begin() + finalCutTemplate.size() - 1, finalCutTemplate.end());
if (nullptr != cutFaceTransform) if (nullptr != cutFaceTransform)
cutFaceTransform->reverse = true; cutFaceTransform->reverse = true;
} }
QVector3D u = QVector3D::crossProduct(finalCutNormal, baseNormal).normalized(); QVector3D u = QVector3D::crossProduct(cutNormal, baseNormal).normalized();
QVector3D v = QVector3D::crossProduct(u, finalCutNormal).normalized(); QVector3D v = QVector3D::crossProduct(u, cutNormal).normalized();
auto uFactor = u * radius; auto uFactor = u * radius;
auto vFactor = v * radius; auto vFactor = v * radius;
if (nullptr != cutFaceTransform) { if (nullptr != cutFaceTransform) {
@ -721,7 +748,7 @@ void Builder::makeCut(const QVector3D &position,
} }
if (!qFuzzyIsNull(degree)) { if (!qFuzzyIsNull(degree)) {
QMatrix4x4 rotation; QMatrix4x4 rotation;
rotation.rotate(degree, traverseDirection); rotation.rotate(degree, cutNormal);
baseNormal = rotation * baseNormal; baseNormal = rotation * baseNormal;
for (auto &positionOnCut: resultCut) { for (auto &positionOnCut: resultCut) {
positionOnCut = rotation * positionOnCut; positionOnCut = rotation * positionOnCut;

View File

@ -25,6 +25,7 @@ public:
size_t addNode(const QVector3D &position, float radius, const std::vector<QVector2D> &cutTemplate); size_t addNode(const QVector3D &position, float radius, const std::vector<QVector2D> &cutTemplate);
size_t addEdge(size_t firstNodeIndex, size_t secondNodeIndex); size_t addEdge(size_t firstNodeIndex, size_t secondNodeIndex);
void setNodeOriginInfo(size_t nodeIndex, int nearOriginNodeIndex, int farOriginNodeIndex);
void setDeformThickness(float thickness); void setDeformThickness(float thickness);
void setDeformWidth(float width); void setDeformWidth(float width);
void setCutRotation(float cutRotation); void setCutRotation(float cutRotation);
@ -50,6 +51,7 @@ private:
std::vector<size_t> edges; std::vector<size_t> edges;
std::vector<QVector2D> cutTemplate; std::vector<QVector2D> cutTemplate;
std::vector<QVector3D> raysToNeibors; std::vector<QVector3D> raysToNeibors;
QVector3D cutNormal;
CutFaceTransform cutFaceTransform; CutFaceTransform cutFaceTransform;
QVector3D initialTraverseDirection; QVector3D initialTraverseDirection;
QVector3D traverseDirection; QVector3D traverseDirection;
@ -62,6 +64,8 @@ private:
bool baseNormalSearched = false; bool baseNormalSearched = false;
bool hasInitialTraverseDirection = false; bool hasInitialTraverseDirection = false;
bool hasAdjustableCutFace = false; bool hasAdjustableCutFace = false;
int nearOriginNodeIndex = -1;
int farOriginNodeIndex = -1;
size_t anotherEdge(size_t edgeIndex) const size_t anotherEdge(size_t edgeIndex) const
{ {
@ -134,7 +138,7 @@ private:
float radius, float radius,
const std::vector<QVector2D> &cutTemplate, const std::vector<QVector2D> &cutTemplate,
QVector3D &baseNormal, QVector3D &baseNormal,
const QVector3D &cutNormal, QVector3D &cutNormal,
const QVector3D &traverseDirection, const QVector3D &traverseDirection,
std::vector<QVector3D> &resultCut, std::vector<QVector3D> &resultCut,
CutFaceTransform *cutFaceTransform=nullptr); CutFaceTransform *cutFaceTransform=nullptr);

View File

@ -117,7 +117,15 @@ void Modifier::finalize()
const Node &firstNode = m_nodes[edge.firstNodeIndex]; const Node &firstNode = m_nodes[edge.firstNodeIndex];
const Node &secondNode = m_nodes[edge.secondNodeIndex]; const Node &secondNode = m_nodes[edge.secondNodeIndex];
createIntermediateNode(firstNode, secondNode, factor, &intermediateNode); createIntermediateNode(firstNode, secondNode, factor, &intermediateNode);
intermediateNode.originNodeIndex = factor <= 0.5 ? firstNode.originNodeIndex : secondNode.originNodeIndex; if (factor <= 0.5) {
intermediateNode.originNodeIndex = firstNode.originNodeIndex;
intermediateNode.nearOriginNodeIndex = firstNode.originNodeIndex;
intermediateNode.farOriginNodeIndex = secondNode.originNodeIndex;
} else {
intermediateNode.originNodeIndex = secondNode.originNodeIndex;
intermediateNode.nearOriginNodeIndex = secondNode.originNodeIndex;
intermediateNode.farOriginNodeIndex = firstNode.originNodeIndex;
}
size_t intermedidateNodeIndex = m_nodes.size(); size_t intermedidateNodeIndex = m_nodes.size();
nodeIndices.push_back(intermedidateNodeIndex); nodeIndices.push_back(intermedidateNodeIndex);
m_nodes.push_back(intermediateNode); m_nodes.push_back(intermediateNode);

View File

@ -15,7 +15,9 @@ public:
QVector3D position; QVector3D position;
float radius = 0.0; float radius = 0.0;
std::vector<QVector2D> cutTemplate; std::vector<QVector2D> cutTemplate;
size_t originNodeIndex = 0; int nearOriginNodeIndex = -1;
int farOriginNodeIndex = -1;
int originNodeIndex = 0;
}; };
struct Edge struct Edge