mirror of
https://github.com/SoftFever/OrcaSlicer.git
synced 2025-07-06 22:47:32 -06:00
Merge branch 'main' into VFA-Calibs
This commit is contained in:
commit
4aafa7a90d
52 changed files with 1696 additions and 866 deletions
|
@ -49,7 +49,7 @@ while getopts ":1j:bcdghirsu" opt; do
|
||||||
export CMAKE_BUILD_PARALLEL_LEVEL=1
|
export CMAKE_BUILD_PARALLEL_LEVEL=1
|
||||||
;;
|
;;
|
||||||
j )
|
j )
|
||||||
CMAKE_BUILD_PARALLEL_LEVEL=$OPTARG
|
export CMAKE_BUILD_PARALLEL_LEVEL=$OPTARG
|
||||||
;;
|
;;
|
||||||
b )
|
b )
|
||||||
BUILD_DEBUG="1"
|
BUILD_DEBUG="1"
|
||||||
|
|
|
@ -3453,8 +3453,8 @@ msgstr ""
|
||||||
|
|
||||||
#, possible-c-format, possible-boost-format
|
#, possible-c-format, possible-boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
|
@ -3691,11 +3691,11 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La temperatura recomanada del broquet d'aquest tipus de filament és de [%d, "
|
"La temperatura recomanada del broquet d'aquest tipus de filament és de [%d, "
|
||||||
"%d] graus centígrads"
|
"%d] graus Celsius."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Too small max volumetric speed.\n"
|
"Too small max volumetric speed.\n"
|
||||||
|
|
|
@ -3618,8 +3618,8 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Doporučená teplota trysky pro tento typ filamentu je [%d, %d]stupňů Celsia"
|
"Doporučená teplota trysky pro tento typ filamentu je [%d, %d]stupňů Celsia"
|
||||||
|
|
||||||
|
@ -18139,7 +18139,7 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Teplota podložky ostatních vrstev je nižší než teplota podložky první "
|
#~ "Teplota podložky ostatních vrstev je nižší než teplota podložky první "
|
||||||
|
|
|
@ -3732,10 +3732,10 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Die empfohlene Düsentemperatur für diesen Filamenttyp beträgt [%d, %d] °C"
|
"Die empfohlene Düsentemperatur für diesen Filamenttyp beträgt [%d, %d] °C."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Too small max volumetric speed.\n"
|
"Too small max volumetric speed.\n"
|
||||||
|
@ -20600,7 +20600,7 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Die Betttemperatur der anderen Schicht ist um mehr als %d Grad Celsius "
|
#~ "Die Betttemperatur der anderen Schicht ist um mehr als %d Grad Celsius "
|
||||||
|
|
|
@ -3585,11 +3585,9 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
|
||||||
"centigrade"
|
|
||||||
msgstr ""
|
|
||||||
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"degrees centigrade"
|
"degrees Celsius."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Too small max volumetric speed.\n"
|
"Too small max volumetric speed.\n"
|
||||||
|
@ -17677,11 +17675,11 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "The bed temperature of other layers is lower than the bed temperature of "
|
#~ "The bed temperature of other layers is lower than the bed temperature of "
|
||||||
#~ "the first layer by more than %d degrees centigrade.\n"
|
#~ "the first layer by more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause models to break free from the build plate during printing."
|
#~ "This may cause models to break free from the build plate during printing."
|
||||||
|
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
|
|
|
@ -3722,11 +3722,11 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La temperatura recomendada de la boquilla para este tipo de filamento es de "
|
"La temperatura recomendada de la boquilla para este tipo de filamento es de "
|
||||||
"[%d, %d] grados centígrados"
|
"[%d, %d] grados Celsius."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Too small max volumetric speed.\n"
|
"Too small max volumetric speed.\n"
|
||||||
|
@ -20194,7 +20194,7 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "La temperatura del lecho de la otra capa es inferior a la temperatura del "
|
#~ "La temperatura del lecho de la otra capa es inferior a la temperatura del "
|
||||||
|
|
|
@ -15,7 +15,7 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n==0 || n==1) ? 0 : 1;\n"
|
"Plural-Forms: nplurals=2; plural=(n==0 || n==1) ? 0 : 1;\n"
|
||||||
"X-Generator: Poedit 3.5\n"
|
"X-Generator: Poedit 3.6\n"
|
||||||
|
|
||||||
msgid "Supports Painting"
|
msgid "Supports Painting"
|
||||||
msgstr "Peindre les supports"
|
msgstr "Peindre les supports"
|
||||||
|
@ -3731,11 +3731,11 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La température de buse recommandée pour ce type de filament est de [%d, %d] "
|
"La température de buse recommandée pour ce type de filament est de [%d, %d] "
|
||||||
"degrés centigrades"
|
"degrés Celsius."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Too small max volumetric speed.\n"
|
"Too small max volumetric speed.\n"
|
||||||
|
@ -3823,10 +3823,10 @@ msgid ""
|
||||||
"YES - Keep Prime Tower\n"
|
"YES - Keep Prime Tower\n"
|
||||||
"NO - Keep Adaptive Layer Height and Independent Support Layer Height"
|
"NO - Keep Adaptive Layer Height and Independent Support Layer Height"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge ne fonctionne pas lorsque la hauteur de couche adaptative "
|
"La tour d’amorçage ne fonctionne pas lorsque la hauteur de couche adaptative "
|
||||||
"ou la hauteur de couche de support indépendante est activée. \n"
|
"ou la hauteur de couche de support indépendante est activée. \n"
|
||||||
"Que souhaitez-vous conserver ? \n"
|
"Que souhaitez-vous conserver ? \n"
|
||||||
"OUI - Conserver la tour de purge \n"
|
"OUI - Conserver la tour d’amorçage \n"
|
||||||
"NON - Conserver la hauteur de la couche adaptative et la hauteur de la "
|
"NON - Conserver la hauteur de la couche adaptative et la hauteur de la "
|
||||||
"couche de support indépendante"
|
"couche de support indépendante"
|
||||||
|
|
||||||
|
@ -3836,10 +3836,10 @@ msgid ""
|
||||||
"YES - Keep Prime Tower\n"
|
"YES - Keep Prime Tower\n"
|
||||||
"NO - Keep Adaptive Layer Height"
|
"NO - Keep Adaptive Layer Height"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge ne fonctionne pas lorsque la hauteur de couche adaptative "
|
"La tour d’amorçage ne fonctionne pas lorsque la hauteur de couche adaptative "
|
||||||
"est activée. \n"
|
"est activée. \n"
|
||||||
"Que souhaitez-vous conserver ? \n"
|
"Que souhaitez-vous conserver ? \n"
|
||||||
"OUI - Conserver la tour de purge \n"
|
"OUI - Conserver la tour d’amorçage \n"
|
||||||
"NON - Conserver la hauteur de la couche adaptative"
|
"NON - Conserver la hauteur de la couche adaptative"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -3848,7 +3848,7 @@ msgid ""
|
||||||
"YES - Keep Prime Tower\n"
|
"YES - Keep Prime Tower\n"
|
||||||
"NO - Keep Independent Support Layer Height"
|
"NO - Keep Independent Support Layer Height"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge ne fonctionne pas lorsque la hauteur de la couche de "
|
"La tour d’amorçage ne fonctionne pas lorsque la hauteur de la couche de "
|
||||||
"support indépendante est activée.\n"
|
"support indépendante est activée.\n"
|
||||||
"Que souhaitez-vous conserver ?\n"
|
"Que souhaitez-vous conserver ?\n"
|
||||||
"OUI - Garder la tour de purge\n"
|
"OUI - Garder la tour de purge\n"
|
||||||
|
@ -4943,7 +4943,7 @@ msgid ""
|
||||||
"top/bottom/side views"
|
"top/bottom/side views"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Passage automatique de la vue en plan à la vue en perspective lorsque l’on "
|
"Passage automatique de la vue en plan à la vue en perspective lorsque l’on "
|
||||||
"passe d’une vue de haut en bas ou de côté à une vue orthographique."
|
"passe d’une vue de haut en bas ou de côté à une vue orthographique"
|
||||||
|
|
||||||
msgid "Show &G-code Window"
|
msgid "Show &G-code Window"
|
||||||
msgstr "Afficher la fenêtre du &G-code"
|
msgstr "Afficher la fenêtre du &G-code"
|
||||||
|
@ -5892,8 +5892,8 @@ msgstr[1] "%1$d L'objets sont mis en couleur."
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid "%1$d object was loaded as a part of cut object."
|
msgid "%1$d object was loaded as a part of cut object."
|
||||||
msgid_plural "%1$d objects were loaded as parts of cut object"
|
msgid_plural "%1$d objects were loaded as parts of cut object"
|
||||||
msgstr[0] "%1$d objet a été chargé en tant que partie de l’objet coupé"
|
msgstr[0] "%1$d objet a été chargé en tant que partie de l’objet coupé."
|
||||||
msgstr[1] "%1$d objets ont été chargés en tant que partie de l’objet coupé"
|
msgstr[1] "%1$d objets ont été chargés en tant que partie de l’objet coupé."
|
||||||
|
|
||||||
msgid "ERROR"
|
msgid "ERROR"
|
||||||
msgstr "ERREUR"
|
msgstr "ERREUR"
|
||||||
|
@ -6775,7 +6775,7 @@ msgstr ""
|
||||||
"La plaque% d : %s n'est pas suggéré pour l'utilisation du filament "
|
"La plaque% d : %s n'est pas suggéré pour l'utilisation du filament "
|
||||||
"d'impression %s(%s). Si vous souhaitez toujours effectuer ce travail "
|
"d'impression %s(%s). Si vous souhaitez toujours effectuer ce travail "
|
||||||
"d'impression, veuillez régler la température du plateau de ce filament sur "
|
"d'impression, veuillez régler la température du plateau de ce filament sur "
|
||||||
"un nombre différent de zéro"
|
"un nombre différent de zéro."
|
||||||
|
|
||||||
msgid "Switching the language requires application restart.\n"
|
msgid "Switching the language requires application restart.\n"
|
||||||
msgstr "Le changement de langue nécessite le redémarrage de l'application.\n"
|
msgstr "Le changement de langue nécessite le redémarrage de l'application.\n"
|
||||||
|
@ -7864,16 +7864,16 @@ msgid ""
|
||||||
"Prime tower is required for smooth timelapse. There may be flaws on the "
|
"Prime tower is required for smooth timelapse. There may be flaws on the "
|
||||||
"model without prime tower. Are you sure you want to disable prime tower?"
|
"model without prime tower. Are you sure you want to disable prime tower?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Une tour de purge est requise pour le mode Timeplase fluide. Il peut y avoir "
|
"Une tour d’amorçage est requise pour le mode Timeplase fluide. Il peut y "
|
||||||
"des défauts sur le modèle sans tour de purge. Êtes-vous sûr de vouloir la "
|
"avoir des défauts sur le modèle sans tour de purge. Êtes-vous sûr de vouloir "
|
||||||
"désactiver ?"
|
"la désactiver ?"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Prime tower is required for smooth timelapse. There may be flaws on the "
|
"Prime tower is required for smooth timelapse. There may be flaws on the "
|
||||||
"model without prime tower. Do you want to enable prime tower?"
|
"model without prime tower. Do you want to enable prime tower?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Une tour de purge est requise pour un mode timelapse fluide. Il peut y avoir "
|
"Une tour d’amorçage est requise pour un mode timelapse fluide. Il peut y "
|
||||||
"des défauts sur le modèle sans tour de purge. Voulez-vous activer la "
|
"avoir des défauts sur le modèle sans tour de purge. Voulez-vous activer la "
|
||||||
"désactiver?"
|
"désactiver?"
|
||||||
|
|
||||||
msgid "Still print by object?"
|
msgid "Still print by object?"
|
||||||
|
@ -8124,7 +8124,7 @@ msgid "Multimaterial"
|
||||||
msgstr "Multi-matériaux"
|
msgstr "Multi-matériaux"
|
||||||
|
|
||||||
msgid "Prime tower"
|
msgid "Prime tower"
|
||||||
msgstr "Tour de purge"
|
msgstr "Tour d’amorçage"
|
||||||
|
|
||||||
msgid "Filament for Features"
|
msgid "Filament for Features"
|
||||||
msgstr "Filament pour les caractéristiques"
|
msgstr "Filament pour les caractéristiques"
|
||||||
|
@ -9724,7 +9724,7 @@ msgstr ""
|
||||||
"de l'impression."
|
"de l'impression."
|
||||||
|
|
||||||
msgid "Prime Tower"
|
msgid "Prime Tower"
|
||||||
msgstr "Tour de purge"
|
msgstr "Tour d’amorçage"
|
||||||
|
|
||||||
msgid " is too close to others, and collisions may be caused.\n"
|
msgid " is too close to others, and collisions may be caused.\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -9827,57 +9827,57 @@ msgid ""
|
||||||
"The prime tower is currently only supported for the Marlin, RepRap/Sprinter, "
|
"The prime tower is currently only supported for the Marlin, RepRap/Sprinter, "
|
||||||
"RepRapFirmware and Repetier G-code flavors."
|
"RepRapFirmware and Repetier G-code flavors."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour principale n’est actuellement prise en charge que pour les versions "
|
"La tour d’amorçage n’est actuellement prise en charge que pour les versions "
|
||||||
"Marlin, RepRap/Sprinter, RepRapFirmware et Repetier G-code."
|
"Marlin, RepRap/Sprinter, RepRapFirmware et Repetier G-code."
|
||||||
|
|
||||||
msgid "The prime tower is not supported in \"By object\" print."
|
msgid "The prime tower is not supported in \"By object\" print."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge n'est pas prise en charge dans l'impression \"Par objet\"."
|
"La tour d’amorçage n'est pas prise en charge dans l'impression \"Par objet\"."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"The prime tower is not supported when adaptive layer height is on. It "
|
"The prime tower is not supported when adaptive layer height is on. It "
|
||||||
"requires that all objects have the same layer height."
|
"requires that all objects have the same layer height."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge n'est pas prise en charge lorsque la hauteur de couche "
|
"La tour d’amorçage n'est pas prise en charge lorsque la hauteur de couche "
|
||||||
"adaptative est activée. Cela nécessite que tous les objets aient la même "
|
"adaptative est activée. Cela nécessite que tous les objets aient la même "
|
||||||
"hauteur de couche."
|
"hauteur de couche."
|
||||||
|
|
||||||
msgid "The prime tower requires \"support gap\" to be multiple of layer height"
|
msgid "The prime tower requires \"support gap\" to be multiple of layer height"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge nécessite que \"l'écart de support\" soit un multiple de la "
|
"La tour d’amorçage nécessite que \"l'écart de support\" soit un multiple de "
|
||||||
"hauteur de la couche"
|
"la hauteur de la couche"
|
||||||
|
|
||||||
msgid "The prime tower requires that all objects have the same layer heights"
|
msgid "The prime tower requires that all objects have the same layer heights"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge nécessite que tous les objets aient la même hauteur de "
|
"La tour d’amorçage nécessite que tous les objets aient la même hauteur de "
|
||||||
"couche"
|
"couche"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"The prime tower requires that all objects are printed over the same number "
|
"The prime tower requires that all objects are printed over the same number "
|
||||||
"of raft layers"
|
"of raft layers"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge nécessite que tous les objets soient imprimés sur le même "
|
"La tour d’amorçage nécessite que tous les objets soient imprimés sur le même "
|
||||||
"nombre de couche de radeau"
|
"nombre de couche de radeau"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"The prime tower is only supported for multiple objects if they are printed "
|
"The prime tower is only supported for multiple objects if they are printed "
|
||||||
"with the same support_top_z_distance"
|
"with the same support_top_z_distance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge n’est prise en charge pour plusieurs objets que s’ils sont "
|
"La tour d’amorçage n’est prise en charge pour plusieurs objets que s’ils "
|
||||||
"imprimés avec la même valeur de support_top_z_distance."
|
"sont imprimés avec la même valeur de support_top_z_distance."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"The prime tower requires that all objects are sliced with the same layer "
|
"The prime tower requires that all objects are sliced with the same layer "
|
||||||
"heights."
|
"heights."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge nécessite que tous les objets soient découpés avec la même "
|
"La tour d’amorçage nécessite que tous les objets soient découpés avec la "
|
||||||
"hauteur de couche."
|
"même hauteur de couche."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"The prime tower is only supported if all objects have the same variable "
|
"The prime tower is only supported if all objects have the same variable "
|
||||||
"layer height"
|
"layer height"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge n'est prise en charge que si tous les objets ont la même "
|
"La tour d’amorçage n'est prise en charge que si tous les objets ont la même "
|
||||||
"hauteur de couche variable"
|
"hauteur de couche variable"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -9906,8 +9906,8 @@ msgstr ""
|
||||||
msgid ""
|
msgid ""
|
||||||
"The prime tower requires that support has the same layer height with object."
|
"The prime tower requires that support has the same layer height with object."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La tour de purge nécessite que le support ait la même hauteur de couche avec "
|
"La tour d’amorçage nécessite que le support ait la même hauteur de couche "
|
||||||
"l'objet."
|
"avec l'objet."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Organic support tree tip diameter must not be smaller than support material "
|
"Organic support tree tip diameter must not be smaller than support material "
|
||||||
|
@ -14546,7 +14546,7 @@ msgstr ""
|
||||||
"une vidéo timelapse une fois l'impression terminée. Si le mode lisse est "
|
"une vidéo timelapse une fois l'impression terminée. Si le mode lisse est "
|
||||||
"sélectionné, l'extrudeur se déplace vers la goulotte d'évacuation à chaque "
|
"sélectionné, l'extrudeur se déplace vers la goulotte d'évacuation à chaque "
|
||||||
"couche imprimée, puis prend un cliché. Étant donné que le filament fondu "
|
"couche imprimée, puis prend un cliché. Étant donné que le filament fondu "
|
||||||
"peut s'échapper de la buse pendant la prise de vue, une tour de purge est "
|
"peut s'échapper de la buse pendant la prise de vue, une tour d’amorçage est "
|
||||||
"requise en mode lisse pour essuyer la buse."
|
"requise en mode lisse pour essuyer la buse."
|
||||||
|
|
||||||
msgid "Traditional"
|
msgid "Traditional"
|
||||||
|
@ -14623,10 +14623,10 @@ msgstr ""
|
||||||
"PAUSE pour déclencher l’action de changement manuel de filament."
|
"PAUSE pour déclencher l’action de changement manuel de filament."
|
||||||
|
|
||||||
msgid "Purge in prime tower"
|
msgid "Purge in prime tower"
|
||||||
msgstr "Purge dans la tour de purge"
|
msgstr "Purge dans la tour d’amorçage"
|
||||||
|
|
||||||
msgid "Purge remaining filament into prime tower"
|
msgid "Purge remaining filament into prime tower"
|
||||||
msgstr "Purger le filament restant dans la tour de purge"
|
msgstr "Purger le filament restant dans la tour d’amorçage"
|
||||||
|
|
||||||
msgid "Enable filament ramming"
|
msgid "Enable filament ramming"
|
||||||
msgstr "Activer le pilonnage du filament"
|
msgstr "Activer le pilonnage du filament"
|
||||||
|
@ -14952,8 +14952,8 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La couche de support utilise la hauteur de la couche indépendamment de la "
|
"La couche de support utilise la hauteur de la couche indépendamment de la "
|
||||||
"couche objet. Cela permet de personnaliser l’écart de Z et de gagner du "
|
"couche objet. Cela permet de personnaliser l’écart de Z et de gagner du "
|
||||||
"temps d'impression. Cette option ne sera pas valide lorsque la tour de purge "
|
"temps d'impression. Cette option ne sera pas valide lorsque la tour "
|
||||||
"sera activée."
|
"d’amorçage sera activée."
|
||||||
|
|
||||||
msgid "Threshold angle"
|
msgid "Threshold angle"
|
||||||
msgstr "Angle de seuil"
|
msgstr "Angle de seuil"
|
||||||
|
@ -15305,13 +15305,13 @@ msgstr ""
|
||||||
"purge multiplié par les volumes de purge dans le tableau."
|
"purge multiplié par les volumes de purge dans le tableau."
|
||||||
|
|
||||||
msgid "Prime volume"
|
msgid "Prime volume"
|
||||||
msgstr "Premier volume"
|
msgstr "Volume d’amorçage"
|
||||||
|
|
||||||
msgid "The volume of material to prime extruder on tower."
|
msgid "The volume of material to prime extruder on tower."
|
||||||
msgstr "Le volume de matériau pour amorcer l'extrudeur sur la tour."
|
msgstr "Le volume de matériau pour amorcer l'extrudeur sur la tour."
|
||||||
|
|
||||||
msgid "Width of prime tower"
|
msgid "Width of prime tower"
|
||||||
msgstr "Largeur de la tour de purge"
|
msgstr "Largeur de la tour d’amorçage"
|
||||||
|
|
||||||
msgid "Wipe tower rotation angle"
|
msgid "Wipe tower rotation angle"
|
||||||
msgstr "Angle de rotation de la tour d’essuyage"
|
msgstr "Angle de rotation de la tour d’essuyage"
|
||||||
|
@ -15405,7 +15405,7 @@ msgstr ""
|
||||||
"matériaux de remplissage des objets. Cela peut réduire la quantité de "
|
"matériaux de remplissage des objets. Cela peut réduire la quantité de "
|
||||||
"déchets et le temps d'impression. Si les parois sont imprimées avec un "
|
"déchets et le temps d'impression. Si les parois sont imprimées avec un "
|
||||||
"filament transparent, le remplissage de couleurs mélangées sera visible. "
|
"filament transparent, le remplissage de couleurs mélangées sera visible. "
|
||||||
"Cela ne prendra effet que si la tour de purge est activée."
|
"Cela ne prendra effet que si la tour d’amorçage est activée."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Purging after filament change will be done inside objects' support. This may "
|
"Purging after filament change will be done inside objects' support. This may "
|
||||||
|
@ -15414,7 +15414,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La purge après le changement de filament se fera à l'intérieur du support "
|
"La purge après le changement de filament se fera à l'intérieur du support "
|
||||||
"des objets. Cela peut réduire la quantité de déchets et le temps "
|
"des objets. Cela peut réduire la quantité de déchets et le temps "
|
||||||
"d'impression. Cela ne prendra effet que si une tour de purge est activée."
|
"d'impression. Cela ne prendra effet que si une tour d’amorçage est activée."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"This object will be used to purge the nozzle after a filament change to save "
|
"This object will be used to purge the nozzle after a filament change to save "
|
||||||
|
@ -15424,7 +15424,7 @@ msgstr ""
|
||||||
"Cet objet sera utilisé pour purger la buse après un changement de filament "
|
"Cet objet sera utilisé pour purger la buse après un changement de filament "
|
||||||
"afin d'économiser du filament et de réduire le temps d'impression. Les "
|
"afin d'économiser du filament et de réduire le temps d'impression. Les "
|
||||||
"couleurs des objets seront mélangées en conséquence. Cela ne prendra effet "
|
"couleurs des objets seront mélangées en conséquence. Cela ne prendra effet "
|
||||||
"que si la tour de purge est activée."
|
"que si la tour d’amorçage est activée."
|
||||||
|
|
||||||
msgid "Maximal bridging distance"
|
msgid "Maximal bridging distance"
|
||||||
msgstr "Distance de pont maximale"
|
msgstr "Distance de pont maximale"
|
||||||
|
@ -20773,7 +20773,7 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "La température du plateau des autres couches est inférieure à la "
|
#~ "La température du plateau des autres couches est inférieure à la "
|
||||||
|
|
|
@ -3620,8 +3620,8 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Az ajánlott fúvóka hőmérséklet ehhez a filament típushoz [%d, %d] Celsius-fok"
|
"Az ajánlott fúvóka hőmérséklet ehhez a filament típushoz [%d, %d] Celsius-fok"
|
||||||
|
|
||||||
|
@ -17907,7 +17907,7 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "A többi réteg asztalhőmérséklete több mint %d Celsius-fokkal alacsonyabb, "
|
#~ "A többi réteg asztalhőmérséklete több mint %d Celsius-fokkal alacsonyabb, "
|
||||||
|
|
|
@ -3725,11 +3725,11 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"La temperatura dell'ugello consigliata per questo filamento è [%d, %d] gradi "
|
"La temperatura dell'ugello consigliata per questo filamento è [%d, %d] gradi "
|
||||||
"centigradi"
|
"Celsius."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Too small max volumetric speed.\n"
|
"Too small max volumetric speed.\n"
|
||||||
|
@ -20244,11 +20244,11 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "The bed temperature of other layers is lower than the bed temperature of "
|
#~ "The bed temperature of other layers is lower than the bed temperature of "
|
||||||
#~ "the first layer by more than %d degrees centigrade.\n"
|
#~ "the first layer by more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause models to break free from the build plate during printing."
|
#~ "This may cause models to break free from the build plate during printing."
|
||||||
|
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
|
|
|
@ -3579,8 +3579,8 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr "このフィラメントで推奨ノズル温度は %d ~ %d ℃です。"
|
msgstr "このフィラメントで推奨ノズル温度は %d ~ %d ℃です。"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -17653,7 +17653,7 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "ベッド温度が1層目温度より %d ℃以上低いです。造形中プレートより離脱する可能"
|
#~ "ベッド温度が1層目温度より %d ℃以上低いです。造形中プレートより離脱する可能"
|
||||||
|
|
|
@ -3594,8 +3594,8 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr "이 필라멘트 유형의 권장 노즐 온도는 [%d, %d]°C입니다"
|
msgstr "이 필라멘트 유형의 권장 노즐 온도는 [%d, %d]°C입니다"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -19244,7 +19244,7 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "다른 레이어의 베드 온도가 초기 레이어의 베드 온도보다 %d°C 이상 낮습니"
|
#~ "다른 레이어의 베드 온도가 초기 레이어의 베드 온도보다 %d°C 이상 낮습니"
|
||||||
|
|
|
@ -3657,11 +3657,11 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"De aanbevolen mondstuk temperatuur voor dit type filament is [%d, %d] graden "
|
"De aanbevolen mondstuk temperatuur voor dit type filament is [%d, %d] graden "
|
||||||
"Celsius"
|
"Celsius."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Too small max volumetric speed.\n"
|
"Too small max volumetric speed.\n"
|
||||||
|
@ -18231,10 +18231,10 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "De printbed temperatuur voor de overige lagen is %d graden celcius lager "
|
#~ "De printbed temperatuur voor de overige lagen is %d graden Celcius lager "
|
||||||
#~ "dan de temperatuur voor de eerste laag.\n"
|
#~ "dan de temperatuur voor de eerste laag.\n"
|
||||||
#~ "Hierdoor kan de print loskomen van het printbed gedurende de printtaak"
|
#~ "Hierdoor kan de print loskomen van het printbed gedurende de printtaak"
|
||||||
|
|
||||||
|
|
|
@ -3688,8 +3688,8 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Zalecana temperatura dyszy dla tego typu filamentu wynosi [%d, %d] stopni "
|
"Zalecana temperatura dyszy dla tego typu filamentu wynosi [%d, %d] stopni "
|
||||||
"Celsjusza"
|
"Celsjusza"
|
||||||
|
@ -21391,7 +21391,7 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Temperatura podłoża innych warstw jest niższa niż temperatura podłoża "
|
#~ "Temperatura podłoża innych warstw jest niższa niż temperatura podłoża "
|
||||||
|
|
|
@ -1785,7 +1785,7 @@ msgid "Delete the selected object"
|
||||||
msgstr "Apagar o objeto selecionado"
|
msgstr "Apagar o objeto selecionado"
|
||||||
|
|
||||||
msgid "Load..."
|
msgid "Load..."
|
||||||
msgstr "Carregar..."
|
msgstr "Carregar…"
|
||||||
|
|
||||||
msgid "Cube"
|
msgid "Cube"
|
||||||
msgstr "Cubo"
|
msgstr "Cubo"
|
||||||
|
@ -2458,7 +2458,7 @@ msgid "No printer"
|
||||||
msgstr "Sem impressora"
|
msgstr "Sem impressora"
|
||||||
|
|
||||||
msgid "..."
|
msgid "..."
|
||||||
msgstr "..."
|
msgstr "…"
|
||||||
|
|
||||||
msgid "Failed to connect to the server"
|
msgid "Failed to connect to the server"
|
||||||
msgstr "Falha ao conectar ao servidor"
|
msgstr "Falha ao conectar ao servidor"
|
||||||
|
@ -2486,7 +2486,7 @@ msgid "Please check the network connection of the printer and Orca."
|
||||||
msgstr "Por favor, verifique a conexão de rede da impressora e do Orca."
|
msgstr "Por favor, verifique a conexão de rede da impressora e do Orca."
|
||||||
|
|
||||||
msgid "Connecting..."
|
msgid "Connecting..."
|
||||||
msgstr "Conectando..."
|
msgstr "Conectando…"
|
||||||
|
|
||||||
msgid "?"
|
msgid "?"
|
||||||
msgstr "?"
|
msgstr "?"
|
||||||
|
@ -2525,7 +2525,7 @@ msgid "Retry"
|
||||||
msgstr "Tentar Novamente"
|
msgstr "Tentar Novamente"
|
||||||
|
|
||||||
msgid "Calibrating AMS..."
|
msgid "Calibrating AMS..."
|
||||||
msgstr "Calibrando AMS..."
|
msgstr "Calibrando AMS…"
|
||||||
|
|
||||||
msgid "A problem occurred during calibration. Click to view the solution."
|
msgid "A problem occurred during calibration. Click to view the solution."
|
||||||
msgstr "Ocorreu um problema durante a calibração. Clique para ver a solução."
|
msgstr "Ocorreu um problema durante a calibração. Clique para ver a solução."
|
||||||
|
@ -2537,7 +2537,7 @@ msgid "Cancel calibration"
|
||||||
msgstr "Cancelar calibração"
|
msgstr "Cancelar calibração"
|
||||||
|
|
||||||
msgid "Idling..."
|
msgid "Idling..."
|
||||||
msgstr "Em espera..."
|
msgstr "Em espera…"
|
||||||
|
|
||||||
msgid "Heat the nozzle"
|
msgid "Heat the nozzle"
|
||||||
msgstr "Aquecer o bico"
|
msgstr "Aquecer o bico"
|
||||||
|
@ -2594,7 +2594,7 @@ msgstr ""
|
||||||
"Não é possível auto-arranjar nessa placa."
|
"Não é possível auto-arranjar nessa placa."
|
||||||
|
|
||||||
msgid "Arranging..."
|
msgid "Arranging..."
|
||||||
msgstr "Organizando..."
|
msgstr "Organizando…"
|
||||||
|
|
||||||
msgid "Arranging"
|
msgid "Arranging"
|
||||||
msgstr "Organizando"
|
msgstr "Organizando"
|
||||||
|
@ -2642,7 +2642,7 @@ msgstr ""
|
||||||
"Não é possível auto-orientar nessa placa."
|
"Não é possível auto-orientar nessa placa."
|
||||||
|
|
||||||
msgid "Orienting..."
|
msgid "Orienting..."
|
||||||
msgstr "Orientando..."
|
msgstr "Orientando…"
|
||||||
|
|
||||||
msgid "Orienting"
|
msgid "Orienting"
|
||||||
msgstr "Orientando"
|
msgstr "Orientando"
|
||||||
|
@ -3260,7 +3260,7 @@ msgid "Please save project and restart the program."
|
||||||
msgstr "Por favor, salve o projeto e reinicie o programa."
|
msgstr "Por favor, salve o projeto e reinicie o programa."
|
||||||
|
|
||||||
msgid "Processing G-Code from Previous file..."
|
msgid "Processing G-Code from Previous file..."
|
||||||
msgstr "Processando G-code do arquivo anterior..."
|
msgstr "Processando G-code do arquivo anterior…"
|
||||||
|
|
||||||
msgid "Slicing complete"
|
msgid "Slicing complete"
|
||||||
msgstr "Fatiamento concluído"
|
msgstr "Fatiamento concluído"
|
||||||
|
@ -3498,7 +3498,7 @@ msgid "No historical tasks!"
|
||||||
msgstr "Nenhuma tarefa no histórico!"
|
msgstr "Nenhuma tarefa no histórico!"
|
||||||
|
|
||||||
msgid "Loading..."
|
msgid "Loading..."
|
||||||
msgstr "Carregando..."
|
msgstr "Carregando…"
|
||||||
|
|
||||||
msgid "No AMS"
|
msgid "No AMS"
|
||||||
msgstr "Nenhum AMS"
|
msgstr "Nenhum AMS"
|
||||||
|
@ -3614,7 +3614,7 @@ msgid "Circular"
|
||||||
msgstr "Circular"
|
msgstr "Circular"
|
||||||
|
|
||||||
msgid "Load shape from STL..."
|
msgid "Load shape from STL..."
|
||||||
msgstr "Carregar forma de STL..."
|
msgstr "Carregar forma de STL…"
|
||||||
|
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Configurações"
|
msgstr "Configurações"
|
||||||
|
@ -3686,11 +3686,11 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"A temperatura do bico recomendada para este tipo de filamento é [%d, %d] "
|
"A temperatura do bico recomendada para este tipo de filamento é [%d, %d] "
|
||||||
"graus centígrados"
|
"graus Celsius."
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Too small max volumetric speed.\n"
|
"Too small max volumetric speed.\n"
|
||||||
|
@ -4991,7 +4991,7 @@ msgid "VFA"
|
||||||
msgstr "VFA"
|
msgstr "VFA"
|
||||||
|
|
||||||
msgid "More..."
|
msgid "More..."
|
||||||
msgstr "Mais..."
|
msgstr "Mais…"
|
||||||
|
|
||||||
msgid "Tutorial"
|
msgid "Tutorial"
|
||||||
msgstr "Tutorial"
|
msgstr "Tutorial"
|
||||||
|
@ -5169,7 +5169,7 @@ msgid "Please enter the IP of printer to connect."
|
||||||
msgstr "Por favor, digite o IP da impressora para conectar."
|
msgstr "Por favor, digite o IP da impressora para conectar."
|
||||||
|
|
||||||
msgid "Initializing..."
|
msgid "Initializing..."
|
||||||
msgstr "Inicializando..."
|
msgstr "Inicializando…"
|
||||||
|
|
||||||
msgid "Connection Failed. Please check the network and try again"
|
msgid "Connection Failed. Please check the network and try again"
|
||||||
msgstr "Falha na conexão. Por favor, verifique a rede e tente novamente"
|
msgstr "Falha na conexão. Por favor, verifique a rede e tente novamente"
|
||||||
|
@ -5220,7 +5220,7 @@ msgid "Information"
|
||||||
msgstr "Informação"
|
msgstr "Informação"
|
||||||
|
|
||||||
msgid "Playing..."
|
msgid "Playing..."
|
||||||
msgstr "Reproduzindo..."
|
msgstr "Reproduzindo…"
|
||||||
|
|
||||||
msgid "Year"
|
msgid "Year"
|
||||||
msgstr "Ano"
|
msgstr "Ano"
|
||||||
|
@ -5277,7 +5277,7 @@ msgid "No printers."
|
||||||
msgstr "Nenhuma impressora."
|
msgstr "Nenhuma impressora."
|
||||||
|
|
||||||
msgid "Loading file list..."
|
msgid "Loading file list..."
|
||||||
msgstr "Carregando lista de arquivos..."
|
msgstr "Carregando lista de arquivos…"
|
||||||
|
|
||||||
msgid "No files"
|
msgid "No files"
|
||||||
msgstr "Sem arquivos"
|
msgstr "Sem arquivos"
|
||||||
|
@ -5327,7 +5327,7 @@ msgid "Delete file"
|
||||||
msgstr "Excluir arquivo"
|
msgstr "Excluir arquivo"
|
||||||
|
|
||||||
msgid "Fetching model information..."
|
msgid "Fetching model information..."
|
||||||
msgstr "Obtendo informações do modelo ..."
|
msgstr "Obtendo informações do modelo…"
|
||||||
|
|
||||||
msgid "Failed to fetch model information from printer."
|
msgid "Failed to fetch model information from printer."
|
||||||
msgstr "Falha ao obter informação do modelo da impressora."
|
msgstr "Falha ao obter informação do modelo da impressora."
|
||||||
|
@ -5355,7 +5355,7 @@ msgstr ""
|
||||||
"Título: %s\n"
|
"Título: %s\n"
|
||||||
|
|
||||||
msgid "Download waiting..."
|
msgid "Download waiting..."
|
||||||
msgstr "Aguardando download..."
|
msgstr "Aguardando download…"
|
||||||
|
|
||||||
msgid "Play"
|
msgid "Play"
|
||||||
msgstr "Reproduzir"
|
msgstr "Reproduzir"
|
||||||
|
@ -5368,7 +5368,7 @@ msgstr "Download concluído"
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid "Downloading %d%%..."
|
msgid "Downloading %d%%..."
|
||||||
msgstr "Baixando %d%%..."
|
msgstr "Baixando %d%%…"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
"Reconnecting the printer, the operation cannot be completed immediately, "
|
"Reconnecting the printer, the operation cannot be completed immediately, "
|
||||||
|
@ -5515,10 +5515,10 @@ msgid "Are you sure you want to cancel this print?"
|
||||||
msgstr "Tem certeza de que deseja cancelar esta impressão?"
|
msgstr "Tem certeza de que deseja cancelar esta impressão?"
|
||||||
|
|
||||||
msgid "Downloading..."
|
msgid "Downloading..."
|
||||||
msgstr "Baixando..."
|
msgstr "Baixando…"
|
||||||
|
|
||||||
msgid "Cloud Slicing..."
|
msgid "Cloud Slicing..."
|
||||||
msgstr "Fatiando na Nuvem..."
|
msgstr "Fatiando na Nuvem…"
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid "In Cloud Slicing Queue, there are %s tasks ahead."
|
msgid "In Cloud Slicing Queue, there are %s tasks ahead."
|
||||||
|
@ -6438,13 +6438,13 @@ msgid "Importing Model"
|
||||||
msgstr "Importando Modelo"
|
msgstr "Importando Modelo"
|
||||||
|
|
||||||
msgid "prepare 3mf file..."
|
msgid "prepare 3mf file..."
|
||||||
msgstr "preparar o arquivo 3mf..."
|
msgstr "preparar o arquivo 3mf…"
|
||||||
|
|
||||||
msgid "Download failed, unknown file format."
|
msgid "Download failed, unknown file format."
|
||||||
msgstr "Baixar falhou, formato de arquivo desconhecido."
|
msgstr "Baixar falhou, formato de arquivo desconhecido."
|
||||||
|
|
||||||
msgid "downloading project ..."
|
msgid "downloading project ..."
|
||||||
msgstr "baixando projeto..."
|
msgstr "baixando projeto…"
|
||||||
|
|
||||||
msgid "Download failed, File size exception."
|
msgid "Download failed, File size exception."
|
||||||
msgstr "Baixar falhou, erro no tamanho do arquivo."
|
msgstr "Baixar falhou, erro no tamanho do arquivo."
|
||||||
|
@ -7641,7 +7641,7 @@ msgid "Pin Code"
|
||||||
msgstr "Código PIN"
|
msgstr "Código PIN"
|
||||||
|
|
||||||
msgid "Binding..."
|
msgid "Binding..."
|
||||||
msgstr "Vinculando..."
|
msgstr "Vinculando…"
|
||||||
|
|
||||||
msgid "Please confirm on the printer screen"
|
msgid "Please confirm on the printer screen"
|
||||||
msgstr "Confirme na tela da impressora"
|
msgstr "Confirme na tela da impressora"
|
||||||
|
@ -9220,7 +9220,7 @@ msgid "Manual Setup"
|
||||||
msgstr "Configuração Manual"
|
msgstr "Configuração Manual"
|
||||||
|
|
||||||
msgid "connecting..."
|
msgid "connecting..."
|
||||||
msgstr "conectando..."
|
msgstr "conectando…"
|
||||||
|
|
||||||
msgid "Failed to connect to printer."
|
msgid "Failed to connect to printer."
|
||||||
msgstr "Falha ao conectar à impressora."
|
msgstr "Falha ao conectar à impressora."
|
||||||
|
@ -16329,7 +16329,7 @@ msgstr ""
|
||||||
"Você ainda quer continuar com a calibração?"
|
"Você ainda quer continuar com a calibração?"
|
||||||
|
|
||||||
msgid "Connecting to printer..."
|
msgid "Connecting to printer..."
|
||||||
msgstr "Conectando à impressora..."
|
msgstr "Conectando à impressora…"
|
||||||
|
|
||||||
msgid "The failed test result has been dropped."
|
msgid "The failed test result has been dropped."
|
||||||
msgstr "O resultado do teste falhado foi descartado."
|
msgstr "O resultado do teste falhado foi descartado."
|
||||||
|
@ -16531,7 +16531,7 @@ msgstr ""
|
||||||
"imprime com:"
|
"imprime com:"
|
||||||
|
|
||||||
msgid "material with significant thermal shrinkage/expansion, such as..."
|
msgid "material with significant thermal shrinkage/expansion, such as..."
|
||||||
msgstr "material com significativa contração/expansão térmica, como..."
|
msgstr "material com significativa contração/expansão térmica, como…"
|
||||||
|
|
||||||
msgid "materials with inaccurate filament diameter"
|
msgid "materials with inaccurate filament diameter"
|
||||||
msgstr "materiais com diâmetro de filamento impreciso"
|
msgstr "materiais com diâmetro de filamento impreciso"
|
||||||
|
|
|
@ -3726,8 +3726,8 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Рекомендуемая температура сопла для данного типа пластиковой нити составляет "
|
"Рекомендуемая температура сопла для данного типа пластиковой нити составляет "
|
||||||
"[%d, %d] градусов Цельсия."
|
"[%d, %d] градусов Цельсия."
|
||||||
|
|
|
@ -3594,8 +3594,8 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Rekommenderad nozzel temperatur med denna filament typ är [%d, %d] grader "
|
"Rekommenderad nozzel temperatur med denna filament typ är [%d, %d] grader "
|
||||||
"celius"
|
"celius"
|
||||||
|
@ -17712,7 +17712,7 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Byggplattans temperatur för andra lager är mindre än temperaturen för "
|
#~ "Byggplattans temperatur för andra lager är mindre än temperaturen för "
|
||||||
|
|
|
@ -3647,10 +3647,10 @@ msgstr ""
|
||||||
"Lütfen yazdırmak için sıcaklığı kullanıp kullanmayacağınızdan emin olun.\n"
|
"Lütfen yazdırmak için sıcaklığı kullanıp kullanmayacağınızdan emin olun.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, fuzzy, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Bu filament tipinin tavsiye edilen Nozul sıcaklığı [%d, %d] derece "
|
"Bu filament tipinin tavsiye edilen Nozul sıcaklığı [%d, %d] derece "
|
||||||
"santigrattır"
|
"santigrattır"
|
||||||
|
|
|
@ -3687,8 +3687,8 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Рекомендована температура сопла для цього типу нитки становить [%d, %d] "
|
"Рекомендована температура сопла для цього типу нитки становить [%d, %d] "
|
||||||
"градусів Цельсія"
|
"градусів Цельсія"
|
||||||
|
|
|
@ -3523,8 +3523,8 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr "该耗材的推荐喷嘴温度是[%d, %d]摄氏度"
|
msgstr "该耗材的推荐喷嘴温度是[%d, %d]摄氏度"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
|
@ -17804,7 +17804,7 @@ msgstr ""
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
#~ msgid ""
|
#~ msgid ""
|
||||||
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
#~ "Bed temperature of other layer is lower than bed temperature of initial "
|
||||||
#~ "layer for more than %d degree centigrade.\n"
|
#~ "layer for more than %d degrees Celsius.\n"
|
||||||
#~ "This may cause model broken free from build plate during printing"
|
#~ "This may cause model broken free from build plate during printing"
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "其它层的热床温度比首层热床温度低太多,超过了%d 摄氏度。\n"
|
#~ "其它层的热床温度比首层热床温度低太多,超过了%d 摄氏度。\n"
|
||||||
|
|
|
@ -3527,8 +3527,8 @@ msgstr ""
|
||||||
|
|
||||||
#, c-format, boost-format
|
#, c-format, boost-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"Recommended nozzle temperature of this filament type is [%d, %d] degree "
|
"The recommended nozzle temperature for this filament type is [%d, %d] "
|
||||||
"centigrade"
|
"degrees Celsius."
|
||||||
msgstr "該線材的推薦噴嘴溫度是攝氏 [%d, %d] 度"
|
msgstr "該線材的推薦噴嘴溫度是攝氏 [%d, %d] 度"
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
|
|
5
resources/images/toolbar_reset_zero.svg
Normal file
5
resources/images/toolbar_reset_zero.svg
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.6457 7C10.5448 7 10.4602 6.9247 10.4433 6.82524C10.1226 4.93741 8.47917 3.5 6.5 3.5C4.29086 3.5 2.5 5.29086 2.5 7.5C2.5 9.47929 3.93759 11.1228 5.82559 11.4434C5.92506 11.4603 6.00037 11.5448 6.00037 11.6457V12.7588C6.00037 12.8763 5.89925 12.9688 5.7827 12.9536C3.08405 12.6022 1 10.2945 1 7.5C1 4.46243 3.46243 2 6.5 2C9.29433 2 11.6019 4.08386 11.9536 6.78232C11.9688 6.89888 11.8763 7 11.7587 7H10.6457Z" fill="#FF6F00"/>
|
||||||
|
<path d="M11.1649 9.76271C11.0854 9.87751 10.9156 9.87751 10.8361 9.76271L8.61993 6.5639C8.52803 6.43126 8.62296 6.25 8.78433 6.25H13.2167C13.3781 6.25 13.473 6.43126 13.3811 6.5639L11.1649 9.76271Z" fill="#FF6F00"/>
|
||||||
|
<path d="M8.38678 7.61146C8.38678 8.48963 8.22064 9.15893 7.88836 9.61938C7.56082 10.0798 7.09326 10.31 6.48566 10.31C5.87807 10.31 5.40576 10.0822 5.06873 9.6265C4.73645 9.16605 4.57031 8.49438 4.57031 7.61146C4.57031 6.72855 4.73645 6.05687 5.06873 5.59643C5.40576 5.13598 5.87807 4.90576 6.48566 4.90576C7.09326 4.90576 7.56082 5.13598 7.88836 5.59643C8.22064 6.05687 8.38678 6.72855 8.38678 7.61146ZM5.85908 7.61146C5.85908 8.14786 5.90892 8.54659 6.00861 8.80767C6.11304 9.06874 6.27206 9.19928 6.48566 9.19928C6.69453 9.19928 6.8488 9.06874 6.94848 8.80767C7.04817 8.54184 7.09801 8.14311 7.09801 7.61146C7.09801 7.07982 7.04817 6.68346 6.94848 6.42238C6.8488 6.15656 6.69453 6.02364 6.48566 6.02364C6.27206 6.02364 6.11304 6.15181 6.00861 6.40814C5.90892 6.66447 5.85908 7.06558 5.85908 7.61146Z" fill="#FF6F00"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
4
resources/images/toolbar_reset_zero_hover.svg
Normal file
4
resources/images/toolbar_reset_zero_hover.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.2937 5.6687C9.71589 3.84914 8.01293 2.53076 6.00204 2.53076C3.51563 2.53076 1.5 4.54639 1.5 7.0328C1.5 9.27369 3.13722 11.1322 5.28073 11.4774C5.38062 11.4935 5.4564 11.5783 5.4564 11.6794V12.7916C5.4564 12.9091 5.35522 13.0016 5.23861 12.9868C2.28425 12.6118 0 10.0891 0 7.0328C0 3.71797 2.68721 1.03076 6.00204 1.03076C8.84765 1.03076 11.2307 3.01105 11.8484 5.6687H13.3662C13.5275 5.6687 13.6225 5.84996 13.5306 5.9826L11.0772 9.52371C10.9977 9.63851 10.8279 9.63851 10.7484 9.52371L8.29505 5.9826C8.20315 5.84996 8.29808 5.6687 8.45945 5.6687H10.2937Z" fill="#FF6F00"/>
|
||||||
|
<path d="M7.99414 7.03451C7.99414 7.96884 7.81738 8.68095 7.46384 9.17084C7.11537 9.66073 6.6179 9.90568 5.97144 9.90568C5.32499 9.90568 4.82247 9.66326 4.46389 9.17842C4.11036 8.68852 3.93359 7.97389 3.93359 7.03451C3.93359 6.09513 4.11036 5.38049 4.46389 4.8906C4.82247 4.40071 5.32499 4.15576 5.97144 4.15576C6.6179 4.15576 7.11537 4.40071 7.46384 4.8906C7.81738 5.38049 7.99414 6.09513 7.99414 7.03451ZM5.30479 7.03451C5.30479 7.60521 5.35782 8.02944 5.46387 8.30722C5.57498 8.58499 5.74417 8.72388 5.97144 8.72388C6.19366 8.72388 6.3578 8.58499 6.46386 8.30722C6.56992 8.02439 6.62295 7.60016 6.62295 7.03451C6.62295 6.46886 6.56992 6.04715 6.46386 5.76937C6.3578 5.48655 6.19366 5.34514 5.97144 5.34514C5.74417 5.34514 5.57498 5.4815 5.46387 5.75422C5.35782 6.02695 5.30479 6.45371 5.30479 7.03451Z" fill="#FF6F00"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
|
@ -5384,7 +5384,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description,
|
||||||
ref_speed = EXTRUDER_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm;
|
ref_speed = EXTRUDER_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm;
|
||||||
|
|
||||||
if (EXTRUDER_CONFIG(filament_max_volumetric_speed) > 0) {
|
if (EXTRUDER_CONFIG(filament_max_volumetric_speed) > 0) {
|
||||||
ref_speed = std::min(ref_speed, EXTRUDER_CONFIG(filament_max_volumetric_speed) / path.mm3_per_mm);
|
ref_speed = std::min(ref_speed, EXTRUDER_CONFIG(filament_max_volumetric_speed) / _mm3_per_mm);
|
||||||
}
|
}
|
||||||
if (sloped) {
|
if (sloped) {
|
||||||
ref_speed = std::min(ref_speed, m_config.scarf_joint_speed.get_abs_value(ref_speed));
|
ref_speed = std::min(ref_speed, m_config.scarf_joint_speed.get_abs_value(ref_speed));
|
||||||
|
|
|
@ -442,6 +442,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
float extrusion_speed = std::min(calculate_speed(curr.distance), calculate_speed(next.distance));
|
float extrusion_speed = std::min(calculate_speed(curr.distance), calculate_speed(next.distance));
|
||||||
|
// ORCA: Clamp resulting speed to lowest of calculated speed based on the overhang values and the current speed
|
||||||
|
// Fixes bug where resulting overhang speed is higher than the current speed due to (for example) volumetric flow limits.
|
||||||
|
extrusion_speed = std::min(extrusion_speed, original_speed);
|
||||||
|
|
||||||
if(slowdown_for_curled_edges) {
|
if(slowdown_for_curled_edges) {
|
||||||
float curled_speed = calculate_speed(artificial_distance_to_curled_lines);
|
float curled_speed = calculate_speed(artificial_distance_to_curled_lines);
|
||||||
extrusion_speed = std::min(curled_speed, extrusion_speed); // adjust extrusion speed based on what is smallest - the calculated overhang speed or the artificial curled speed
|
extrusion_speed = std::min(curled_speed, extrusion_speed); // adjust extrusion speed based on what is smallest - the calculated overhang speed or the artificial curled speed
|
||||||
|
|
|
@ -478,6 +478,16 @@ Transform3d Transformation::get_rotation_matrix() const
|
||||||
return extract_rotation_matrix(m_matrix);
|
return extract_rotation_matrix(m_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec3d Transformation::get_rotation_by_quaternion() const
|
||||||
|
{
|
||||||
|
Matrix3d rotation_matrix = m_matrix.matrix().block(0, 0, 3, 3);
|
||||||
|
Eigen::Quaterniond quaternion(rotation_matrix);
|
||||||
|
quaternion.normalize();
|
||||||
|
Vec3d temp_rotation = quaternion.matrix().eulerAngles(2, 1, 0);
|
||||||
|
std::swap(temp_rotation(0), temp_rotation(2));
|
||||||
|
return temp_rotation;
|
||||||
|
}
|
||||||
|
|
||||||
void Transformation::set_rotation(const Vec3d& rotation)
|
void Transformation::set_rotation(const Vec3d& rotation)
|
||||||
{
|
{
|
||||||
const Vec3d offset = get_offset();
|
const Vec3d offset = get_offset();
|
||||||
|
@ -839,6 +849,17 @@ TransformationSVD::TransformationSVD(const Transform3d& trafo)
|
||||||
return curMat;
|
return curMat;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Transformation generate_transform(const Vec3d& x_dir, const Vec3d& y_dir, const Vec3d& z_dir, const Vec3d& origin) {
|
||||||
|
Matrix3d m;
|
||||||
|
m.col(0) = x_dir.normalized();
|
||||||
|
m.col(1) = y_dir.normalized();
|
||||||
|
m.col(2) = z_dir.normalized();
|
||||||
|
Transform3d mm(m);
|
||||||
|
Transformation tran(mm);
|
||||||
|
tran.set_offset(origin);
|
||||||
|
return tran;
|
||||||
|
}
|
||||||
|
|
||||||
bool is_point_inside_polygon_corner(const Point &a, const Point &b, const Point &c, const Point &query_point) {
|
bool is_point_inside_polygon_corner(const Point &a, const Point &b, const Point &c, const Point &query_point) {
|
||||||
// Cast all input points into int64_t to prevent overflows when points are close to max values of coord_t.
|
// Cast all input points into int64_t to prevent overflows when points are close to max values of coord_t.
|
||||||
const Vec2i64 a_i64 = a.cast<int64_t>();
|
const Vec2i64 a_i64 = a.cast<int64_t>();
|
||||||
|
|
|
@ -421,6 +421,7 @@ public:
|
||||||
void set_offset(Axis axis, double offset) { m_matrix.translation()[axis] = offset; }
|
void set_offset(Axis axis, double offset) { m_matrix.translation()[axis] = offset; }
|
||||||
|
|
||||||
Vec3d get_rotation() const;
|
Vec3d get_rotation() const;
|
||||||
|
Vec3d get_rotation_by_quaternion() const;
|
||||||
double get_rotation(Axis axis) const { return get_rotation()[axis]; }
|
double get_rotation(Axis axis) const { return get_rotation()[axis]; }
|
||||||
|
|
||||||
Transform3d get_rotation_matrix() const;
|
Transform3d get_rotation_matrix() const;
|
||||||
|
@ -545,6 +546,7 @@ inline bool is_rotation_ninety_degrees(const Vec3d &rotation)
|
||||||
}
|
}
|
||||||
|
|
||||||
Transformation mat_around_a_point_rotate(const Transformation& innMat, const Vec3d &pt, const Vec3d &axis, float rotate_theta_radian);
|
Transformation mat_around_a_point_rotate(const Transformation& innMat, const Vec3d &pt, const Vec3d &axis, float rotate_theta_radian);
|
||||||
|
Transformation generate_transform(const Vec3d &x_dir, const Vec3d &y_dir, const Vec3d &z_dir, const Vec3d &origin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if a given point is inside a corner of a polygon.
|
* Checks if a given point is inside a corner of a polygon.
|
||||||
|
|
|
@ -1167,23 +1167,27 @@ bool ModelObject::make_boolean(ModelObject *cut_object, const std::string &boole
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelVolume* ModelObject::add_volume(const TriangleMesh &mesh)
|
ModelVolume *ModelObject::add_volume(const TriangleMesh &mesh, bool modify_to_center_geometry)
|
||||||
{
|
{
|
||||||
ModelVolume* v = new ModelVolume(this, mesh);
|
ModelVolume* v = new ModelVolume(this, mesh);
|
||||||
this->volumes.push_back(v);
|
this->volumes.push_back(v);
|
||||||
v->center_geometry_after_creation();
|
if (modify_to_center_geometry) {
|
||||||
this->invalidate_bounding_box();
|
v->center_geometry_after_creation();
|
||||||
|
this->invalidate_bounding_box();
|
||||||
|
}
|
||||||
// BBS: backup
|
// BBS: backup
|
||||||
Slic3r::save_object_mesh(*this);
|
Slic3r::save_object_mesh(*this);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelVolume* ModelObject::add_volume(TriangleMesh &&mesh, ModelVolumeType type /*= ModelVolumeType::MODEL_PART*/)
|
ModelVolume *ModelObject::add_volume(TriangleMesh &&mesh, ModelVolumeType type /*= ModelVolumeType::MODEL_PART*/, bool modify_to_center_geometry)
|
||||||
{
|
{
|
||||||
ModelVolume* v = new ModelVolume(this, std::move(mesh), type);
|
ModelVolume* v = new ModelVolume(this, std::move(mesh), type);
|
||||||
this->volumes.push_back(v);
|
this->volumes.push_back(v);
|
||||||
v->center_geometry_after_creation();
|
if (modify_to_center_geometry) {
|
||||||
this->invalidate_bounding_box();
|
v->center_geometry_after_creation();
|
||||||
|
this->invalidate_bounding_box();
|
||||||
|
}
|
||||||
// BBS: backup
|
// BBS: backup
|
||||||
Slic3r::save_object_mesh(*this);
|
Slic3r::save_object_mesh(*this);
|
||||||
return v;
|
return v;
|
||||||
|
|
|
@ -410,8 +410,8 @@ public:
|
||||||
return global_config.option<T>(config_option);
|
return global_config.option<T>(config_option);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelVolume* add_volume(const TriangleMesh &mesh);
|
ModelVolume* add_volume(const TriangleMesh &mesh, bool modify_to_center_geometry = true);
|
||||||
ModelVolume* add_volume(TriangleMesh &&mesh, ModelVolumeType type = ModelVolumeType::MODEL_PART);
|
ModelVolume* add_volume(TriangleMesh &&mesh, ModelVolumeType type = ModelVolumeType::MODEL_PART, bool modify_to_center_geometry = true);
|
||||||
ModelVolume* add_volume(const ModelVolume &volume, ModelVolumeType type = ModelVolumeType::INVALID);
|
ModelVolume* add_volume(const ModelVolume &volume, ModelVolumeType type = ModelVolumeType::INVALID);
|
||||||
ModelVolume* add_volume(const ModelVolume &volume, TriangleMesh &&mesh);
|
ModelVolume* add_volume(const ModelVolume &volume, TriangleMesh &&mesh);
|
||||||
ModelVolume* add_volume_with_shared_mesh(const ModelVolume &other, ModelVolumeType type = ModelVolumeType::MODEL_PART);
|
ModelVolume* add_volume_with_shared_mesh(const ModelVolume &other, ModelVolumeType type = ModelVolumeType::MODEL_PART);
|
||||||
|
@ -1244,11 +1244,13 @@ public:
|
||||||
m_assemble_initialized = true;
|
m_assemble_initialized = true;
|
||||||
m_assemble_transformation = transformation;
|
m_assemble_transformation = transformation;
|
||||||
}
|
}
|
||||||
void set_assemble_from_transform(Transform3d& transform) {
|
void set_assemble_from_transform(const Transform3d& transform) {
|
||||||
m_assemble_initialized = true;
|
m_assemble_initialized = true;
|
||||||
m_assemble_transformation.set_matrix(transform);
|
m_assemble_transformation.set_matrix(transform);
|
||||||
}
|
}
|
||||||
|
Vec3d get_assemble_offset() const {return m_assemble_transformation.get_offset(); }
|
||||||
void set_assemble_offset(const Vec3d& offset) { m_assemble_transformation.set_offset(offset); }
|
void set_assemble_offset(const Vec3d& offset) { m_assemble_transformation.set_offset(offset); }
|
||||||
|
void set_assemble_rotation(const Vec3d &rotation) { m_assemble_transformation.set_rotation(rotation); }
|
||||||
void rotate_assemble(double angle, const Vec3d& axis) {
|
void rotate_assemble(double angle, const Vec3d& axis) {
|
||||||
m_assemble_transformation.set_rotation(m_assemble_transformation.get_rotation() + Geometry::extract_euler_angles(Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis)).toRotationMatrix()));
|
m_assemble_transformation.set_rotation(m_assemble_transformation.get_rotation() + Geometry::extract_euler_angles(Eigen::Quaterniond(Eigen::AngleAxisd(angle, axis)).toRotationMatrix()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -895,8 +895,13 @@ int GLVolumeCollection::get_selection_support_threshold_angle(bool &enable_suppo
|
||||||
}
|
}
|
||||||
|
|
||||||
//BBS: add outline drawing logic
|
//BBS: add outline drawing logic
|
||||||
void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix, const GUI::Size& cnv_size,
|
void GLVolumeCollection::render(GLVolumeCollection::ERenderType type,
|
||||||
std::function<bool(const GLVolume&)> filter_func) const
|
bool disable_cullface,
|
||||||
|
const Transform3d & view_matrix,
|
||||||
|
const Transform3d& projection_matrix,
|
||||||
|
const GUI::Size& cnv_size,
|
||||||
|
std::function<bool(const GLVolume &)> filter_func,
|
||||||
|
bool partly_inside_enable) const
|
||||||
{
|
{
|
||||||
GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func);
|
GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func);
|
||||||
if (to_render.empty())
|
if (to_render.empty())
|
||||||
|
@ -964,7 +969,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab
|
||||||
//shader->set_uniform("print_volume.xy_data", m_render_volume.data);
|
//shader->set_uniform("print_volume.xy_data", m_render_volume.data);
|
||||||
//shader->set_uniform("print_volume.z_data", m_render_volume.zs);
|
//shader->set_uniform("print_volume.z_data", m_render_volume.zs);
|
||||||
|
|
||||||
if (volume.first->partly_inside) {
|
if (volume.first->partly_inside && partly_inside_enable) {
|
||||||
//only partly inside volume need to be painted with boundary check
|
//only partly inside volume need to be painted with boundary check
|
||||||
shader->set_uniform("print_volume.type", static_cast<int>(m_print_volume.type));
|
shader->set_uniform("print_volume.type", static_cast<int>(m_print_volume.type));
|
||||||
shader->set_uniform("print_volume.xy_data", m_print_volume.data);
|
shader->set_uniform("print_volume.xy_data", m_print_volume.data);
|
||||||
|
|
|
@ -471,8 +471,14 @@ public:
|
||||||
int get_selection_support_threshold_angle(bool&) const;
|
int get_selection_support_threshold_angle(bool&) const;
|
||||||
// Render the volumes by OpenGL.
|
// Render the volumes by OpenGL.
|
||||||
//BBS: add outline drawing logic
|
//BBS: add outline drawing logic
|
||||||
void render(ERenderType type, bool disable_cullface, const Transform3d& view_matrix, const Transform3d& projection_matrix, const GUI::Size& cnv_size,
|
void render(ERenderType type,
|
||||||
std::function<bool(const GLVolume &)> filter_func = std::function<bool(const GLVolume &)>()) const;
|
bool disable_cullface,
|
||||||
|
const Transform3d & view_matrix,
|
||||||
|
const Transform3d& projection_matrix,
|
||||||
|
const GUI::Size& cnv_size,
|
||||||
|
std::function<bool(const GLVolume &)> filter_func = std::function<bool(const GLVolume &)>(),
|
||||||
|
bool partly_inside_enable =true
|
||||||
|
) const;
|
||||||
|
|
||||||
// Clear the geometry
|
// Clear the geometry
|
||||||
void clear() { for (auto *v : volumes) delete v; volumes.clear(); }
|
void clear() { for (auto *v : volumes) delete v; volumes.clear(); }
|
||||||
|
|
|
@ -90,7 +90,7 @@ void ConfigManipulation::check_nozzle_temperature_range(DynamicPrintConfig *conf
|
||||||
if (config->opt_int("nozzle_temperature", 0) < temperature_range_low || config->opt_int("nozzle_temperature", 0) > temperature_range_high) {
|
if (config->opt_int("nozzle_temperature", 0) < temperature_range_low || config->opt_int("nozzle_temperature", 0) > temperature_range_high) {
|
||||||
wxString msg_text = _(L("Nozzle may be blocked when the temperature is out of recommended range.\n"
|
wxString msg_text = _(L("Nozzle may be blocked when the temperature is out of recommended range.\n"
|
||||||
"Please make sure whether to use the temperature to print.\n\n"));
|
"Please make sure whether to use the temperature to print.\n\n"));
|
||||||
msg_text += wxString::Format(_L("Recommended nozzle temperature of this filament type is [%d, %d] degree centigrade"), temperature_range_low, temperature_range_high);
|
msg_text += wxString::Format(_L("The recommended nozzle temperature for this filament type is [%d, %d] degrees Celsius."), temperature_range_low, temperature_range_high);
|
||||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||||
is_msg_dlg_already_exist = true;
|
is_msg_dlg_already_exist = true;
|
||||||
dialog.ShowModal();
|
dialog.ShowModal();
|
||||||
|
@ -113,7 +113,7 @@ void ConfigManipulation::check_nozzle_temperature_initial_layer_range(DynamicPri
|
||||||
{
|
{
|
||||||
wxString msg_text = _(L("Nozzle may be blocked when the temperature is out of recommended range.\n"
|
wxString msg_text = _(L("Nozzle may be blocked when the temperature is out of recommended range.\n"
|
||||||
"Please make sure whether to use the temperature to print.\n\n"));
|
"Please make sure whether to use the temperature to print.\n\n"));
|
||||||
msg_text += wxString::Format(_L("Recommended nozzle temperature of this filament type is [%d, %d] degree centigrade"), temperature_range_low, temperature_range_high);
|
msg_text += wxString::Format(_L("The recommended nozzle temperature for this filament type is [%d, %d] degrees Celsius."), temperature_range_low, temperature_range_high);
|
||||||
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
MessageDialog dialog(m_msg_dlg_parent, msg_text, "", wxICON_WARNING | wxOK);
|
||||||
is_msg_dlg_already_exist = true;
|
is_msg_dlg_already_exist = true;
|
||||||
dialog.ShowModal();
|
dialog.ShowModal();
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "libslic3r/Technologies.hpp"
|
#include "libslic3r/Technologies.hpp"
|
||||||
#include "libslic3r/Tesselate.hpp"
|
#include "libslic3r/Tesselate.hpp"
|
||||||
#include "libslic3r/PresetBundle.hpp"
|
#include "libslic3r/PresetBundle.hpp"
|
||||||
#include "3DBed.hpp"
|
|
||||||
#include "3DScene.hpp"
|
#include "3DScene.hpp"
|
||||||
#include "BackgroundSlicingProcess.hpp"
|
#include "BackgroundSlicingProcess.hpp"
|
||||||
#include "GLShader.hpp"
|
#include "GLShader.hpp"
|
||||||
|
@ -1168,6 +1167,13 @@ GLCanvas3D::GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed)
|
||||||
load_arrange_settings();
|
load_arrange_settings();
|
||||||
|
|
||||||
m_selection.set_volumes(&m_volumes.volumes);
|
m_selection.set_volumes(&m_volumes.volumes);
|
||||||
|
|
||||||
|
m_assembly_view_desc["object_selection_caption"] = _L("Left mouse button");
|
||||||
|
m_assembly_view_desc["object_selection"] = _L("object selection");
|
||||||
|
m_assembly_view_desc["part_selection_caption"] = "Alt +" + _L("Left mouse button");
|
||||||
|
m_assembly_view_desc["part_selection"] = _L("part selectiont");
|
||||||
|
m_assembly_view_desc["number_key_caption"] = "1~16 " + _L("number keys");
|
||||||
|
m_assembly_view_desc["number_key"] = _L("number keys can quickly change the color of objects");
|
||||||
}
|
}
|
||||||
|
|
||||||
GLCanvas3D::~GLCanvas3D()
|
GLCanvas3D::~GLCanvas3D()
|
||||||
|
@ -1939,7 +1945,11 @@ void GLCanvas3D::render(bool only_init)
|
||||||
/* assemble render*/
|
/* assemble render*/
|
||||||
else if (m_canvas_type == ECanvasType::CanvasAssembleView) {
|
else if (m_canvas_type == ECanvasType::CanvasAssembleView) {
|
||||||
//BBS: add outline logic
|
//BBS: add outline logic
|
||||||
|
if (m_show_world_axes) {
|
||||||
|
m_axes.render();
|
||||||
|
}
|
||||||
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
|
_render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running());
|
||||||
|
_render_selection();
|
||||||
//_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes);
|
//_render_bed(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), show_axes);
|
||||||
_render_plane();
|
_render_plane();
|
||||||
//BBS: add outline logic insteadof selection under assemble view
|
//BBS: add outline logic insteadof selection under assemble view
|
||||||
|
@ -2147,6 +2157,9 @@ void GLCanvas3D::update_plate_thumbnails()
|
||||||
|
|
||||||
void GLCanvas3D::select_all()
|
void GLCanvas3D::select_all()
|
||||||
{
|
{
|
||||||
|
if (!m_gizmos.is_allow_select_all()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_selection.add_all();
|
m_selection.add_all();
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
@ -2262,16 +2275,10 @@ std::vector<int> GLCanvas3D::load_object(const Model& model, int obj_idx)
|
||||||
void GLCanvas3D::mirror_selection(Axis axis)
|
void GLCanvas3D::mirror_selection(Axis axis)
|
||||||
{
|
{
|
||||||
TransformationType transformation_type;
|
TransformationType transformation_type;
|
||||||
if (wxGetApp().obj_manipul()->is_local_coordinates())
|
//transformation_type.set_world();
|
||||||
transformation_type.set_local();
|
|
||||||
else if (wxGetApp().obj_manipul()->is_instance_coordinates())
|
|
||||||
transformation_type.set_instance();
|
|
||||||
|
|
||||||
transformation_type.set_relative();
|
transformation_type.set_relative();
|
||||||
|
|
||||||
m_selection.setup_cache();
|
m_selection.setup_cache();
|
||||||
m_selection.mirror(axis, transformation_type);
|
m_selection.mirror(axis, transformation_type);
|
||||||
|
|
||||||
do_mirror(L("Mirror Object"));
|
do_mirror(L("Mirror Object"));
|
||||||
// BBS
|
// BBS
|
||||||
//wxGetApp().obj_manipul()->set_dirty();
|
//wxGetApp().obj_manipul()->set_dirty();
|
||||||
|
@ -4073,9 +4080,7 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
GLGizmosManager::EType c = m_gizmos.get_current_type();
|
GLGizmosManager::EType c = m_gizmos.get_current_type();
|
||||||
if (current_printer_technology() == ptFFF &&
|
if (current_printer_technology() == ptFFF &&
|
||||||
(fff_print()->config().print_sequence == PrintSequence::ByObject)) {
|
(fff_print()->config().print_sequence == PrintSequence::ByObject)) {
|
||||||
if (c == GLGizmosManager::EType::Move ||
|
if (can_sequential_clearance_show_in_gizmo())
|
||||||
c == GLGizmosManager::EType::Scale ||
|
|
||||||
c == GLGizmosManager::EType::Rotate )
|
|
||||||
update_sequential_clearance();
|
update_sequential_clearance();
|
||||||
} else {
|
} else {
|
||||||
if (c == GLGizmosManager::EType::Move ||
|
if (c == GLGizmosManager::EType::Move ||
|
||||||
|
@ -4178,11 +4183,22 @@ void GLCanvas3D::on_mouse(wxMouseEvent& evt)
|
||||||
int volume_idx = get_first_hover_volume_idx();
|
int volume_idx = get_first_hover_volume_idx();
|
||||||
bool already_selected = m_selection.contains_volume(volume_idx);
|
bool already_selected = m_selection.contains_volume(volume_idx);
|
||||||
bool ctrl_down = evt.CmdDown();
|
bool ctrl_down = evt.CmdDown();
|
||||||
|
bool alt_down = evt.AltDown();
|
||||||
Selection::IndicesList curr_idxs = m_selection.get_volume_idxs();
|
Selection::IndicesList curr_idxs = m_selection.get_volume_idxs();
|
||||||
|
|
||||||
if (already_selected && ctrl_down)
|
if (already_selected && ctrl_down)
|
||||||
m_selection.remove(volume_idx);
|
m_selection.remove(volume_idx);
|
||||||
|
else if (alt_down) {
|
||||||
|
Selection::EMode mode = Selection::Volume;
|
||||||
|
if (already_selected) {
|
||||||
|
std::vector<unsigned int> volume_idxs;
|
||||||
|
for (auto idx : curr_idxs) { volume_idxs.emplace_back(idx); }
|
||||||
|
m_selection.remove_volumes(mode, volume_idxs);
|
||||||
|
}
|
||||||
|
std::vector<unsigned int> add_volume_idxs;
|
||||||
|
add_volume_idxs.emplace_back(volume_idx);
|
||||||
|
m_selection.add_volumes(mode, add_volume_idxs, true);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
m_selection.add(volume_idx, !ctrl_down, true);
|
m_selection.add(volume_idx, !ctrl_down, true);
|
||||||
m_mouse.drag.move_requires_threshold = !already_selected;
|
m_mouse.drag.move_requires_threshold = !already_selected;
|
||||||
|
@ -4660,11 +4676,19 @@ void GLCanvas3D::do_move(const std::string& snapshot_type)
|
||||||
// Move instances/volumes
|
// Move instances/volumes
|
||||||
ModelObject* model_object = m_model->objects[object_idx];
|
ModelObject* model_object = m_model->objects[object_idx];
|
||||||
if (model_object != nullptr) {
|
if (model_object != nullptr) {
|
||||||
if (selection_mode == Selection::Instance)
|
if (selection_mode == Selection::Instance) {
|
||||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
if (m_canvas_type == GLCanvas3D::ECanvasType::CanvasAssembleView) {
|
||||||
|
if ((model_object->instances[instance_idx]->get_assemble_offset() - v->get_instance_offset()).norm() > 1e-2) {
|
||||||
|
model_object->instances[instance_idx]->set_assemble_transformation(v->get_instance_transformation());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (selection_mode == Selection::Volume) {
|
else if (selection_mode == Selection::Volume) {
|
||||||
if (model_object->volumes[volume_idx]->get_transformation() != v->get_volume_transformation()) {
|
auto cur_mv = model_object->volumes[volume_idx];
|
||||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
if (cur_mv->get_transformation() != v->get_volume_transformation()) {
|
||||||
|
cur_mv->set_transformation(v->get_volume_transformation());
|
||||||
// BBS: backup
|
// BBS: backup
|
||||||
Slic3r::save_object_mesh(*model_object);
|
Slic3r::save_object_mesh(*model_object);
|
||||||
}
|
}
|
||||||
|
@ -4771,11 +4795,17 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
|
||||||
// Rotate instances/volumes.
|
// Rotate instances/volumes.
|
||||||
ModelObject* model_object = m_model->objects[object_idx];
|
ModelObject* model_object = m_model->objects[object_idx];
|
||||||
if (model_object != nullptr) {
|
if (model_object != nullptr) {
|
||||||
if (selection_mode == Selection::Instance)
|
if (selection_mode == Selection::Instance) {
|
||||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
if (m_canvas_type == GLCanvas3D::ECanvasType::CanvasAssembleView) {
|
||||||
|
model_object->instances[instance_idx]->set_assemble_from_transform(v->get_instance_transformation().get_matrix());
|
||||||
|
} else {
|
||||||
|
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (selection_mode == Selection::Volume) {
|
else if (selection_mode == Selection::Volume) {
|
||||||
if (model_object->volumes[volume_idx]->get_transformation() != v->get_volume_transformation()) {
|
auto cur_mv = model_object->volumes[volume_idx];
|
||||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
if (cur_mv->get_transformation() != v->get_volume_transformation()) {
|
||||||
|
cur_mv->set_transformation(v->get_volume_transformation());
|
||||||
// BBS: backup
|
// BBS: backup
|
||||||
Slic3r::save_object_mesh(*model_object);
|
Slic3r::save_object_mesh(*model_object);
|
||||||
}
|
}
|
||||||
|
@ -4786,23 +4816,24 @@ void GLCanvas3D::do_rotate(const std::string& snapshot_type)
|
||||||
|
|
||||||
//BBS: notify instance updates to part plater list
|
//BBS: notify instance updates to part plater list
|
||||||
m_selection.notify_instance_update(-1, -1);
|
m_selection.notify_instance_update(-1, -1);
|
||||||
|
if (m_canvas_type != CanvasAssembleView) {
|
||||||
|
// Fixes sinking/flying instances
|
||||||
|
for (const std::pair<int, int> &i : done) {
|
||||||
|
ModelObject *m = m_model->objects[i.first];
|
||||||
|
|
||||||
// Fixes sinking/flying instances
|
// BBS: don't call translate if the z is zero
|
||||||
for (const std::pair<int, int>& i : done) {
|
const double shift_z = m->get_instance_min_z(i.second);
|
||||||
ModelObject* m = m_model->objects[i.first];
|
// leave sinking instances as sinking
|
||||||
|
if ((min_zs.find({i.first, i.second})->second >= SINKING_Z_THRESHOLD || shift_z > SINKING_Z_THRESHOLD) && (shift_z != 0.0f)) {
|
||||||
|
const Vec3d shift(0.0, 0.0, -shift_z);
|
||||||
|
m_selection.translate(i.first, i.second, shift);
|
||||||
|
m->translate_instance(i.second, shift);
|
||||||
|
// BBS: notify instance updates to part plater list
|
||||||
|
m_selection.notify_instance_update(i.first, i.second);
|
||||||
|
}
|
||||||
|
|
||||||
//BBS: don't call translate if the z is zero
|
wxGetApp().obj_list()->update_info_items(static_cast<size_t>(i.first));
|
||||||
const double shift_z = m->get_instance_min_z(i.second);
|
|
||||||
// leave sinking instances as sinking
|
|
||||||
if ((min_zs.find({ i.first, i.second })->second >= SINKING_Z_THRESHOLD || shift_z > SINKING_Z_THRESHOLD)&&(shift_z != 0.0f)) {
|
|
||||||
const Vec3d shift(0.0, 0.0, -shift_z);
|
|
||||||
m_selection.translate(i.first, i.second, shift);
|
|
||||||
m->translate_instance(i.second, shift);
|
|
||||||
//BBS: notify instance updates to part plater list
|
|
||||||
m_selection.notify_instance_update(i.first, i.second);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wxGetApp().obj_list()->update_info_items(static_cast<size_t>(i.first));
|
|
||||||
}
|
}
|
||||||
//BBS: nofity object list to update
|
//BBS: nofity object list to update
|
||||||
wxGetApp().plater()->sidebar().obj_list()->update_plate_values_for_items();
|
wxGetApp().plater()->sidebar().obj_list()->update_plate_values_for_items();
|
||||||
|
@ -4852,12 +4883,14 @@ void GLCanvas3D::do_scale(const std::string& snapshot_type)
|
||||||
// Rotate instances/volumes
|
// Rotate instances/volumes
|
||||||
ModelObject* model_object = m_model->objects[object_idx];
|
ModelObject* model_object = m_model->objects[object_idx];
|
||||||
if (model_object != nullptr) {
|
if (model_object != nullptr) {
|
||||||
if (selection_mode == Selection::Instance)
|
if (selection_mode == Selection::Instance) {
|
||||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||||
|
}
|
||||||
else if (selection_mode == Selection::Volume) {
|
else if (selection_mode == Selection::Volume) {
|
||||||
if (model_object->volumes[volume_idx]->get_transformation() != v->get_volume_transformation()) {
|
auto cur_mv = model_object->volumes[volume_idx];
|
||||||
|
if (cur_mv->get_transformation() != v->get_volume_transformation()) {
|
||||||
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
model_object->instances[instance_idx]->set_transformation(v->get_instance_transformation());
|
||||||
model_object->volumes[volume_idx]->set_transformation(v->get_volume_transformation());
|
cur_mv->set_transformation(v->get_volume_transformation());
|
||||||
// BBS: backup
|
// BBS: backup
|
||||||
Slic3r::save_object_mesh(*model_object);
|
Slic3r::save_object_mesh(*model_object);
|
||||||
}
|
}
|
||||||
|
@ -5213,6 +5246,17 @@ void GLCanvas3D::mouse_up_cleanup()
|
||||||
m_canvas->ReleaseMouse();
|
m_canvas->ReleaseMouse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GLCanvas3D::can_sequential_clearance_show_in_gizmo() {
|
||||||
|
switch (m_gizmos.get_current_type()) {
|
||||||
|
case GLGizmosManager::EType::Move:
|
||||||
|
case GLGizmosManager::EType::Scale:
|
||||||
|
case GLGizmosManager::EType::Rotate: {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void GLCanvas3D::update_sequential_clearance()
|
void GLCanvas3D::update_sequential_clearance()
|
||||||
{
|
{
|
||||||
if (current_printer_technology() != ptFFF || (fff_print()->config().print_sequence == PrintSequence::ByLayer))
|
if (current_printer_technology() != ptFFF || (fff_print()->config().print_sequence == PrintSequence::ByLayer))
|
||||||
|
@ -7269,6 +7313,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
||||||
|
|
||||||
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
|
GLShaderProgram* shader = wxGetApp().get_shader("gouraud");
|
||||||
ECanvasType canvas_type = this->m_canvas_type;
|
ECanvasType canvas_type = this->m_canvas_type;
|
||||||
|
bool partly_inside_enable = canvas_type == ECanvasType::CanvasAssembleView ? false : true;
|
||||||
if (shader != nullptr) {
|
if (shader != nullptr) {
|
||||||
shader->start_using();
|
shader->start_using();
|
||||||
|
|
||||||
|
@ -7312,7 +7357,8 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
||||||
else {
|
else {
|
||||||
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
|
return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0);
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
partly_inside_enable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -7346,7 +7392,8 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with
|
||||||
else {
|
else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
},
|
||||||
|
partly_inside_enable);
|
||||||
if (m_canvas_type == CanvasAssembleView && m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position() > 0) {
|
if (m_canvas_type == CanvasAssembleView && m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position() > 0) {
|
||||||
const GLGizmosManager& gm = get_gizmos_manager();
|
const GLGizmosManager& gm = get_gizmos_manager();
|
||||||
shader->stop_using();
|
shader->stop_using();
|
||||||
|
@ -7414,19 +7461,11 @@ void GLCanvas3D::_render_sequential_clearance()
|
||||||
{
|
{
|
||||||
if (m_gizmos.is_dragging())
|
if (m_gizmos.is_dragging())
|
||||||
return;
|
return;
|
||||||
|
auto type = m_gizmos.get_current_type();
|
||||||
switch (m_gizmos.get_current_type())
|
if (type == GLGizmosManager::EType::Undefined
|
||||||
{
|
|| can_sequential_clearance_show_in_gizmo()) {
|
||||||
case GLGizmosManager::EType::Flatten:
|
m_sequential_print_clearance.render();
|
||||||
case GLGizmosManager::EType::Cut:
|
|
||||||
// case GLGizmosManager::EType::Hollow:
|
|
||||||
// case GLGizmosManager::EType::SlaSupports:
|
|
||||||
case GLGizmosManager::EType::FdmSupports:
|
|
||||||
case GLGizmosManager::EType::Seam: { return; }
|
|
||||||
default: { break; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_sequential_print_clearance.render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_RENDER_SELECTION_CENTER
|
#if ENABLE_RENDER_SELECTION_CENTER
|
||||||
|
@ -8171,6 +8210,7 @@ void GLCanvas3D::_render_return_toolbar() const
|
||||||
wxPostEvent(m_canvas, SimpleEvent(EVT_GLVIEWTOOLBAR_3D));
|
wxPostEvent(m_canvas, SimpleEvent(EVT_GLVIEWTOOLBAR_3D));
|
||||||
const_cast<GLGizmosManager*>(&m_gizmos)->reset_all_states();
|
const_cast<GLGizmosManager*>(&m_gizmos)->reset_all_states();
|
||||||
wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager().reset_all_states();
|
wxGetApp().plater()->get_view3D_canvas3D()->get_gizmos_manager().reset_all_states();
|
||||||
|
wxGetApp().plater()->get_view3D_canvas3D()->reload_scene(true);
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor(5);
|
ImGui::PopStyleColor(5);
|
||||||
ImGui::PopStyleVar(1);
|
ImGui::PopStyleVar(1);
|
||||||
|
@ -8370,8 +8410,45 @@ void GLCanvas3D::_render_paint_toolbar() const
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float GLCanvas3D::_show_assembly_tooltip_information(float caption_max, float x, float y) const
|
||||||
|
{
|
||||||
|
ImGuiWrapper *imgui = wxGetApp().imgui();
|
||||||
|
ImTextureID normal_id = m_gizmos.get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP);
|
||||||
|
ImTextureID hover_id = m_gizmos.get_icon_texture_id(GLGizmosManager::MENU_ICON_NAME::IC_TOOLBAR_TOOLTIP_HOVER);
|
||||||
|
|
||||||
|
caption_max += imgui->calc_text_size(": "sv).x + 35.f;
|
||||||
|
|
||||||
|
float scale = get_scale();
|
||||||
|
ImVec2 button_size = ImVec2(25 * scale, 25 * scale); // ORCA: Use exact resolution will prevent blur on icon
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, {0, ImGui::GetStyle().FramePadding.y});
|
||||||
|
ImGui::ImageButton3(normal_id, hover_id, button_size);
|
||||||
|
|
||||||
|
if (ImGui::IsItemHovered()) {
|
||||||
|
ImGui::BeginTooltip2(ImVec2(x, y));
|
||||||
|
auto draw_text_with_caption = [this, &imgui, & caption_max](const wxString &caption, const wxString &text) {
|
||||||
|
imgui->text_colored(ImGuiWrapper::COL_ACTIVE, caption);
|
||||||
|
ImGui::SameLine(caption_max);
|
||||||
|
imgui->text_colored(ImGuiWrapper::COL_WINDOW_BG, text);
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto &t : std::array<std::string, 3>{"object_selection", "part_selection", "number_key"}) {
|
||||||
|
draw_text_with_caption(m_assembly_view_desc.at(t + "_caption") + ": ", m_assembly_view_desc.at(t));
|
||||||
|
}
|
||||||
|
ImGui::EndTooltip();
|
||||||
|
}
|
||||||
|
ImGui::PopStyleVar(2);
|
||||||
|
auto same_line_size = button_size.x * 1.8;//with an space size
|
||||||
|
ImGui::SameLine(same_line_size);
|
||||||
|
same_line_size = imgui->calc_text_size("|"sv).x + same_line_size + imgui->calc_text_size(" "sv).x;
|
||||||
|
imgui->text_colored(ImGuiWrapper::COL_ACTIVE, "|");
|
||||||
|
ImGui::SameLine(same_line_size);
|
||||||
|
return same_line_size;
|
||||||
|
}
|
||||||
|
|
||||||
//BBS
|
//BBS
|
||||||
void GLCanvas3D::_render_assemble_control() const
|
void GLCanvas3D::_render_assemble_control()
|
||||||
{
|
{
|
||||||
if (m_canvas_type != ECanvasType::CanvasAssembleView) {
|
if (m_canvas_type != ECanvasType::CanvasAssembleView) {
|
||||||
GLVolume::explosion_ratio = m_explosion_ratio = 1.0;
|
GLVolume::explosion_ratio = m_explosion_ratio = 1.0;
|
||||||
|
@ -8392,8 +8469,8 @@ void GLCanvas3D::_render_assemble_control() const
|
||||||
const float text_padding = 7.0f;
|
const float text_padding = 7.0f;
|
||||||
const float text_size_x = std::max(imgui->calc_text_size(_L("Reset direction")).x + 2 * ImGui::GetStyle().FramePadding.x,
|
const float text_size_x = std::max(imgui->calc_text_size(_L("Reset direction")).x + 2 * ImGui::GetStyle().FramePadding.x,
|
||||||
std::max(imgui->calc_text_size(_L("Explosion Ratio")).x, imgui->calc_text_size(_L("Section View")).x));
|
std::max(imgui->calc_text_size(_L("Explosion Ratio")).x, imgui->calc_text_size(_L("Section View")).x));
|
||||||
const float slider_width = 75.0f;
|
const float slider_width = 60.0f;
|
||||||
const float value_size = imgui->calc_text_size(std::string_view{"3.00"}).x + text_padding * 2;
|
const float value_size = imgui->calc_text_size("3.00"sv).x + text_padding * 2;
|
||||||
const float item_spacing = imgui->get_item_spacing().x;
|
const float item_spacing = imgui->get_item_spacing().x;
|
||||||
ImVec2 window_padding = ImGui::GetStyle().WindowPadding;
|
ImVec2 window_padding = ImGui::GetStyle().WindowPadding;
|
||||||
|
|
||||||
|
@ -8401,7 +8478,19 @@ void GLCanvas3D::_render_assemble_control() const
|
||||||
imgui->begin(_L("Assemble Control"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
imgui->begin(_L("Assemble Control"), ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar);
|
||||||
|
|
||||||
ImGui::AlignTextToFramePadding();
|
ImGui::AlignTextToFramePadding();
|
||||||
|
float tip_icon_size;
|
||||||
|
{
|
||||||
|
float caption_max = 0.f;
|
||||||
|
for (const auto &t : std::array<std::string, 3>{"object_selection", "part_selection", "number_key"}) {
|
||||||
|
caption_max = std::max(caption_max, imgui->calc_text_size(m_assembly_view_desc.at(t + "_caption")).x);
|
||||||
|
}
|
||||||
|
const ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||||
|
const float text_y =imgui->calc_text_size(_L("part selection")).y;
|
||||||
|
float get_cur_x = pos.x;
|
||||||
|
float get_cur_y = pos.y - ImGui::GetFrameHeight() - 4 * text_y;
|
||||||
|
tip_icon_size =_show_assembly_tooltip_information(caption_max, get_cur_x, get_cur_y);
|
||||||
|
}
|
||||||
|
float same_line_width = tip_icon_size;
|
||||||
{
|
{
|
||||||
float clp_dist = m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position();
|
float clp_dist = m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position();
|
||||||
if (clp_dist == 0.f) {
|
if (clp_dist == 0.f) {
|
||||||
|
@ -8415,32 +8504,76 @@ void GLCanvas3D::_render_assemble_control() const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
same_line_width += (text_size_x + item_spacing);
|
||||||
ImGui::SameLine(window_padding.x + text_size_x + item_spacing);
|
ImGui::SameLine(same_line_width);
|
||||||
ImGui::PushItemWidth(slider_width);
|
ImGui::PushItemWidth(slider_width);
|
||||||
bool view_slider_changed = imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true);
|
bool view_slider_changed = imgui->bbl_slider_float_style("##clp_dist", &clp_dist, 0.f, 1.f, "%.2f", 1.0f, true);
|
||||||
|
|
||||||
ImGui::SameLine(window_padding.x + text_size_x + slider_width + item_spacing * 2);
|
same_line_width += (slider_width + item_spacing);
|
||||||
|
ImGui::SameLine(same_line_width);
|
||||||
ImGui::PushItemWidth(value_size);
|
ImGui::PushItemWidth(value_size);
|
||||||
bool view_input_changed = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f");
|
bool view_input_changed = ImGui::BBLDragFloat("##clp_dist_input", &clp_dist, 0.05f, 0.0f, 0.0f, "%.2f");
|
||||||
|
|
||||||
if (view_slider_changed || view_input_changed)
|
if (view_slider_changed || view_input_changed)
|
||||||
m_gizmos.m_assemble_view_data->model_objects_clipper()->set_position(clp_dist, true);
|
m_gizmos.m_assemble_view_data->model_objects_clipper()->set_position(clp_dist, true);
|
||||||
}
|
|
||||||
|
|
||||||
|
same_line_width += (value_size + item_spacing * 2);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
ImGui::SameLine(window_padding.x + text_size_x + slider_width + item_spacing * 6 + value_size);
|
auto temp_x = imgui->calc_text_size(_L("Explosion Ratio")).x;
|
||||||
|
ImGui::SameLine(same_line_width);
|
||||||
|
ImGui::PushItemWidth(temp_x);
|
||||||
imgui->text(_L("Explosion Ratio"));
|
imgui->text(_L("Explosion Ratio"));
|
||||||
|
|
||||||
ImGui::SameLine(window_padding.x + 2 * text_size_x + slider_width + item_spacing * 7 + value_size);
|
same_line_width += (temp_x + item_spacing);
|
||||||
|
ImGui::SameLine(same_line_width);
|
||||||
ImGui::PushItemWidth(slider_width);
|
ImGui::PushItemWidth(slider_width);
|
||||||
bool explosion_slider_changed = imgui->bbl_slider_float_style("##ratio_slider", &m_explosion_ratio, 1.0f, 3.0f, "%1.2f");
|
bool explosion_slider_changed = imgui->bbl_slider_float_style("##ratio_slider", &m_explosion_ratio, 1.0f, 3.0f, "%1.2f");
|
||||||
|
|
||||||
ImGui::SameLine(window_padding.x + 2 * text_size_x + 2 * slider_width + item_spacing * 8 + value_size);
|
same_line_width += (slider_width + item_spacing);
|
||||||
|
ImGui::SameLine(same_line_width);
|
||||||
ImGui::PushItemWidth(value_size);
|
ImGui::PushItemWidth(value_size);
|
||||||
bool explosion_input_changed = ImGui::BBLDragFloat("##ratio_input", &m_explosion_ratio, 0.1f, 1.0f, 3.0f, "%1.2f");
|
bool explosion_input_changed = ImGui::BBLDragFloat("##ratio_input", &m_explosion_ratio, 0.1f, 1.0f, 3.0f, "%1.2f");
|
||||||
|
same_line_width += (value_size + item_spacing*2);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
ImGui::SameLine(same_line_width);
|
||||||
|
// input
|
||||||
|
std::vector<std::string> modes = {_u8L("Object"), _u8L("Part")};
|
||||||
|
int selection_idx = m_selection.get_volume_selection_mode() == Selection::Instance ? 0 : 1;
|
||||||
|
auto label = _u8L("Selection Mode") + ":" ;
|
||||||
|
auto label_width = imgui->calc_text_size(label).x ;
|
||||||
|
auto item_width = imgui->calc_text_size(_u8L("Object")).x * 2.5 + imgui->calc_text_size("xx"sv).x+ item_spacing;
|
||||||
|
//render imgui
|
||||||
|
ImGui::AlignTextToFramePadding();
|
||||||
|
ImGui::PushItemWidth(label_width);
|
||||||
|
imgui->text(label);
|
||||||
|
same_line_width += (label_width + item_spacing);
|
||||||
|
ImGui::SameLine(same_line_width);
|
||||||
|
ImGui::PushItemWidth(item_width);
|
||||||
|
size_t selection_out = selection_idx;
|
||||||
|
const char *selected_str = (selection_idx >= 0 && selection_idx < int(modes.size())) ? modes[selection_idx].c_str() : "";
|
||||||
|
ImGuiWrapper::push_combo_style(get_scale());
|
||||||
|
if (ImGui::BBLBeginCombo(("##" + label).c_str(), selected_str, 0)) {
|
||||||
|
for (size_t line_idx = 0; line_idx < modes.size(); ++line_idx) {
|
||||||
|
ImGui::PushID(int(line_idx));
|
||||||
|
if (ImGui::Selectable("", line_idx == selection_idx))
|
||||||
|
selection_out = line_idx;
|
||||||
|
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Text("%s", modes[line_idx].c_str());
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
|
ImGuiWrapper::pop_combo_style();
|
||||||
|
if (selection_idx != selection_out) {//do
|
||||||
|
if (selection_out == 0) { m_selection.unlock_volume_selection_mode(); }
|
||||||
|
m_selection.set_volume_selection_mode(selection_out == 1 ? Selection::Volume : Selection::Instance);
|
||||||
|
if (selection_out == 1) { m_selection.lock_volume_selection_mode(); }
|
||||||
|
}
|
||||||
|
same_line_width += (label_width + item_width);
|
||||||
|
}
|
||||||
imgui->end();
|
imgui->end();
|
||||||
|
|
||||||
ImGuiWrapper::pop_toolbar_style();
|
ImGuiWrapper::pop_toolbar_style();
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
#include "Camera.hpp"
|
#include "Camera.hpp"
|
||||||
#include "SceneRaycaster.hpp"
|
#include "SceneRaycaster.hpp"
|
||||||
#include "IMToolbar.hpp"
|
#include "IMToolbar.hpp"
|
||||||
|
#include "slic3r/GUI/3DBed.hpp"
|
||||||
#include "libslic3r/Slicing.hpp"
|
#include "libslic3r/Slicing.hpp"
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
@ -512,6 +512,7 @@ private:
|
||||||
wxGLContext* m_context;
|
wxGLContext* m_context;
|
||||||
SceneRaycaster m_scene_raycaster;
|
SceneRaycaster m_scene_raycaster;
|
||||||
Bed3D &m_bed;
|
Bed3D &m_bed;
|
||||||
|
std::map<std::string, wxString> m_assembly_view_desc;
|
||||||
#if ENABLE_RETINA_GL
|
#if ENABLE_RETINA_GL
|
||||||
std::unique_ptr<RetinaHelper> m_retina_helper;
|
std::unique_ptr<RetinaHelper> m_retina_helper;
|
||||||
#endif
|
#endif
|
||||||
|
@ -611,8 +612,8 @@ private:
|
||||||
|
|
||||||
PrinterTechnology current_printer_technology() const;
|
PrinterTechnology current_printer_technology() const;
|
||||||
|
|
||||||
|
bool m_show_world_axes{false};
|
||||||
|
Bed3D::Axes m_axes;
|
||||||
//BBS:record key botton frequency
|
//BBS:record key botton frequency
|
||||||
int auto_orient_count = 0;
|
int auto_orient_count = 0;
|
||||||
int auto_arrange_count = 0;
|
int auto_arrange_count = 0;
|
||||||
|
@ -807,6 +808,7 @@ public:
|
||||||
void set_color_clip_plane(const Vec3d& cp_normal, double offset) { m_volumes.set_color_clip_plane(cp_normal, offset); }
|
void set_color_clip_plane(const Vec3d& cp_normal, double offset) { m_volumes.set_color_clip_plane(cp_normal, offset); }
|
||||||
void set_color_clip_plane_colors(const std::array<ColorRGBA, 2>& colors) { m_volumes.set_color_clip_plane_colors(colors); }
|
void set_color_clip_plane_colors(const std::array<ColorRGBA, 2>& colors) { m_volumes.set_color_clip_plane_colors(colors); }
|
||||||
|
|
||||||
|
void set_show_world_axes(bool flag) { m_show_world_axes = flag; }
|
||||||
void refresh_camera_scene_box();
|
void refresh_camera_scene_box();
|
||||||
void set_color_by(const std::string& value);
|
void set_color_by(const std::string& value);
|
||||||
|
|
||||||
|
@ -1111,6 +1113,7 @@ public:
|
||||||
m_sequential_print_clearance.set_polygons(polygons, height_polygons);
|
m_sequential_print_clearance.set_polygons(polygons, height_polygons);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool can_sequential_clearance_show_in_gizmo();
|
||||||
void update_sequential_clearance();
|
void update_sequential_clearance();
|
||||||
|
|
||||||
const Print* fff_print() const;
|
const Print* fff_print() const;
|
||||||
|
@ -1189,7 +1192,8 @@ private:
|
||||||
// BBS
|
// BBS
|
||||||
//void _render_view_toolbar() const;
|
//void _render_view_toolbar() const;
|
||||||
void _render_paint_toolbar() const;
|
void _render_paint_toolbar() const;
|
||||||
void _render_assemble_control() const;
|
float _show_assembly_tooltip_information(float caption_max, float x, float y) const;
|
||||||
|
void _render_assemble_control();
|
||||||
void _render_assemble_info() const;
|
void _render_assemble_info() const;
|
||||||
#if ENABLE_SHOW_CAMERA_TARGET
|
#if ENABLE_SHOW_CAMERA_TARGET
|
||||||
void _render_camera_target();
|
void _render_camera_target();
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace GUI {
|
||||||
|
|
||||||
enum class ECoordinatesType : unsigned char
|
enum class ECoordinatesType : unsigned char
|
||||||
{
|
{
|
||||||
World,
|
World = 0,
|
||||||
Instance,
|
Instance,
|
||||||
Local
|
Local
|
||||||
};
|
};
|
||||||
|
|
|
@ -4759,6 +4759,9 @@ void ObjectList::select_all()
|
||||||
|
|
||||||
void ObjectList::select_item_all_children()
|
void ObjectList::select_item_all_children()
|
||||||
{
|
{
|
||||||
|
if (wxGetApp().plater() && !wxGetApp().plater()->canvas3D()->get_gizmos_manager().is_allow_select_all()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
wxDataViewItemArray sels;
|
wxDataViewItemArray sels;
|
||||||
|
|
||||||
// There is no selection before OR some object is selected => select all objects
|
// There is no selection before OR some object is selected => select all objects
|
||||||
|
|
|
@ -823,10 +823,10 @@ bool AssembleView::init(wxWindow* parent, Bed3D& bed, Model* model, DynamicPrint
|
||||||
m_canvas->enable_assemble_view_toolbar(false);
|
m_canvas->enable_assemble_view_toolbar(false);
|
||||||
m_canvas->enable_return_toolbar(true);
|
m_canvas->enable_return_toolbar(true);
|
||||||
m_canvas->enable_separator_toolbar(false);
|
m_canvas->enable_separator_toolbar(false);
|
||||||
|
//m_canvas->set_show_world_axes(true);//wait for GitHub users to see if they have this requirement
|
||||||
// BBS: set volume_selection_mode to Volume
|
// BBS: set volume_selection_mode to Volume
|
||||||
m_canvas->get_selection().set_volume_selection_mode(Selection::Volume);
|
//same to 3d //m_canvas->get_selection().set_volume_selection_mode(Selection::Instance);
|
||||||
m_canvas->get_selection().lock_volume_selection_mode();
|
//m_canvas->get_selection().lock_volume_selection_mode();
|
||||||
|
|
||||||
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
|
wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL);
|
||||||
main_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);
|
main_sizer->Add(m_canvas_widget, 1, wxALL | wxEXPAND, 0);
|
||||||
|
|
|
@ -227,7 +227,71 @@ bool GLGizmoBase::render_combo(const std::string &label, const std::vector<std::
|
||||||
return is_changed;
|
return is_changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLGizmoBase::GLGizmoBase(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id)
|
void GLGizmoBase::render_cross_mark(const Vec3f &target, bool is_single)
|
||||||
|
{
|
||||||
|
const float half_length = 4.0f;
|
||||||
|
|
||||||
|
glsafe(::glLineWidth(2.0f));
|
||||||
|
|
||||||
|
auto render_line = [](const Vec3f& p1, const Vec3f& p2, const ColorRGBA& color) {
|
||||||
|
GLModel::Geometry init_data;
|
||||||
|
init_data.format = {GLModel::Geometry::EPrimitiveType::Lines, GLModel::Geometry::EVertexLayout::P3};
|
||||||
|
init_data.color = color;
|
||||||
|
init_data.reserve_vertices(2);
|
||||||
|
init_data.reserve_indices(2);
|
||||||
|
|
||||||
|
// vertices
|
||||||
|
init_data.add_vertex(p1);
|
||||||
|
init_data.add_vertex(p2);
|
||||||
|
|
||||||
|
// indices
|
||||||
|
init_data.add_line(0, 1);
|
||||||
|
|
||||||
|
GLModel model;
|
||||||
|
model.init_from(std::move(init_data));
|
||||||
|
model.render();
|
||||||
|
};
|
||||||
|
|
||||||
|
// draw line for x axis
|
||||||
|
if (!is_single) {
|
||||||
|
render_line(
|
||||||
|
{target(0) - half_length, target(1), target(2)},
|
||||||
|
{target(0) + half_length, target(1), target(2)},
|
||||||
|
ColorRGBA::RED());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
render_line(
|
||||||
|
{target(0), target(1), target(2)},
|
||||||
|
{target(0) + half_length, target(1), target(2)},
|
||||||
|
ColorRGBA::RED());
|
||||||
|
}
|
||||||
|
// draw line for y axis
|
||||||
|
if (!is_single) {
|
||||||
|
render_line(
|
||||||
|
{target(0), target(1) - half_length, target(2)},
|
||||||
|
{target(0), target(1) + half_length, target(2)},
|
||||||
|
ColorRGBA::GREEN());
|
||||||
|
} else {
|
||||||
|
render_line(
|
||||||
|
{target(0), target(1), target(2)},
|
||||||
|
{target(0), target(1) + half_length, target(2)},
|
||||||
|
ColorRGBA::GREEN());
|
||||||
|
}
|
||||||
|
// draw line for z axis
|
||||||
|
if (!is_single) {
|
||||||
|
render_line(
|
||||||
|
{target(0), target(1), target(2) - half_length},
|
||||||
|
{target(0), target(1), target(2) + half_length},
|
||||||
|
ColorRGBA::BLUE());
|
||||||
|
} else {
|
||||||
|
render_line(
|
||||||
|
{target(0), target(1), target(2)},
|
||||||
|
{target(0), target(1), target(2) + half_length},
|
||||||
|
ColorRGBA::BLUE());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLGizmoBase::GLGizmoBase(GLCanvas3D &parent, const std::string &icon_filename, unsigned int sprite_id)
|
||||||
: m_parent(parent)
|
: m_parent(parent)
|
||||||
, m_group_id(-1)
|
, m_group_id(-1)
|
||||||
, m_state(Off)
|
, m_state(Off)
|
||||||
|
|
|
@ -152,7 +152,7 @@ protected:
|
||||||
|
|
||||||
bool render_combo(const std::string &label, const std::vector<std::string> &lines,
|
bool render_combo(const std::string &label, const std::vector<std::string> &lines,
|
||||||
int &selection_idx, float label_width, float item_width);
|
int &selection_idx, float label_width, float item_width);
|
||||||
|
void render_cross_mark(const Vec3f& target,bool is_single =false);
|
||||||
public:
|
public:
|
||||||
GLGizmoBase(GLCanvas3D& parent,
|
GLGizmoBase(GLCanvas3D& parent,
|
||||||
const std::string& icon_filename,
|
const std::string& icon_filename,
|
||||||
|
|
|
@ -48,6 +48,7 @@ bool GLGizmoMove3D::on_mouse(const wxMouseEvent &mouse_event) {
|
||||||
|
|
||||||
void GLGizmoMove3D::data_changed(bool is_serializing) {
|
void GLGizmoMove3D::data_changed(bool is_serializing) {
|
||||||
m_grabbers[2].enabled = !m_parent.get_selection().is_wipe_tower();
|
m_grabbers[2].enabled = !m_parent.get_selection().is_wipe_tower();
|
||||||
|
change_cs_by_selection();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoMove3D::on_init()
|
bool GLGizmoMove3D::on_init()
|
||||||
|
@ -67,7 +68,11 @@ bool GLGizmoMove3D::on_init()
|
||||||
|
|
||||||
std::string GLGizmoMove3D::on_get_name() const
|
std::string GLGizmoMove3D::on_get_name() const
|
||||||
{
|
{
|
||||||
return _u8L("Move");
|
if (!on_is_activable() && m_state == EState::Off) {
|
||||||
|
return _u8L("Move") + ":\n" + _u8L("Please select at least one object.");
|
||||||
|
} else {
|
||||||
|
return _u8L("Move");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoMove3D::on_is_activable() const
|
bool GLGizmoMove3D::on_is_activable() const
|
||||||
|
@ -75,13 +80,21 @@ bool GLGizmoMove3D::on_is_activable() const
|
||||||
return !m_parent.get_selection().is_empty();
|
return !m_parent.get_selection().is_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoMove3D::on_set_state() {
|
||||||
|
if (get_state() == On) {
|
||||||
|
m_last_selected_obejct_idx = -1;
|
||||||
|
m_last_selected_volume_idx = -1;
|
||||||
|
change_cs_by_selection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoMove3D::on_start_dragging()
|
void GLGizmoMove3D::on_start_dragging()
|
||||||
{
|
{
|
||||||
assert(m_hover_id != -1);
|
assert(m_hover_id != -1);
|
||||||
|
|
||||||
m_displacement = Vec3d::Zero();
|
m_displacement = Vec3d::Zero();
|
||||||
const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box();
|
const BoundingBoxf3& box = m_parent.get_selection().get_bounding_box();
|
||||||
m_starting_drag_position = m_grabbers[m_hover_id].center;
|
m_starting_drag_position = m_grabbers[m_hover_id].matrix * m_grabbers[m_hover_id].center;
|
||||||
m_starting_box_center = box.center();
|
m_starting_box_center = box.center();
|
||||||
m_starting_box_bottom_center = box.center();
|
m_starting_box_bottom_center = box.center();
|
||||||
m_starting_box_bottom_center(2) = box.min(2);
|
m_starting_box_bottom_center(2) = box.min(2);
|
||||||
|
@ -121,42 +134,38 @@ void GLGizmoMove3D::on_render()
|
||||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
const BoundingBoxf3& box = selection.get_bounding_box();
|
const auto &[box, box_trafo] = selection.get_bounding_box_in_current_reference_system();
|
||||||
const Vec3d& center = box.center();
|
m_bounding_box = box;
|
||||||
|
m_center = box_trafo.translation();
|
||||||
|
if (m_object_manipulation) {
|
||||||
|
m_object_manipulation->cs_center = box_trafo.translation();
|
||||||
|
}
|
||||||
|
const Transform3d base_matrix = box_trafo;
|
||||||
float space_size = 20.f *INV_ZOOM;
|
float space_size = 20.f *INV_ZOOM;
|
||||||
|
|
||||||
#if ENABLE_FIXED_GRABBER
|
for (int i = 0; i < 3; ++i) {
|
||||||
|
m_grabbers[i].matrix = base_matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vec3d zero = Vec3d::Zero();
|
||||||
|
|
||||||
// x axis
|
// x axis
|
||||||
m_grabbers[0].center = { box.max.x() + space_size, center.y(), center.z() };
|
m_grabbers[0].center = {m_bounding_box.max.x() + space_size, 0, 0};
|
||||||
// y axis
|
// y axis
|
||||||
m_grabbers[1].center = { center.x(), box.max.y() + space_size, center.z() };
|
m_grabbers[1].center = {0, m_bounding_box.max.y() + space_size,0};
|
||||||
// z axis
|
// z axis
|
||||||
m_grabbers[2].center = { center.x(), center.y(), box.max.z() + space_size };
|
m_grabbers[2].center = {0,0, m_bounding_box.max.z() + space_size};
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
m_grabbers[i].color = AXES_COLOR[i];
|
m_grabbers[i].color = AXES_COLOR[i];
|
||||||
m_grabbers[i].hover_color = AXES_HOVER_COLOR[i];
|
m_grabbers[i].hover_color = AXES_HOVER_COLOR[i];
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
// x axis
|
|
||||||
m_grabbers[0].center = { box.max.x() + Offset, center.y(), center.z() };
|
|
||||||
m_grabbers[0].color = AXES_COLOR[0];
|
|
||||||
|
|
||||||
// y axis
|
|
||||||
m_grabbers[1].center = { center.x(), box.max.y() + Offset, center.z() };
|
|
||||||
m_grabbers[1].color = AXES_COLOR[1];
|
|
||||||
|
|
||||||
// z axis
|
|
||||||
m_grabbers[2].center = { center.x(), center.y(), box.max.z() + Offset };
|
|
||||||
m_grabbers[2].color = AXES_COLOR[2];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
|
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
|
||||||
|
|
||||||
auto render_grabber_connection = [this, ¢er](unsigned int id) {
|
auto render_grabber_connection = [this, &zero](unsigned int id) {
|
||||||
if (m_grabbers[id].enabled) {
|
if (m_grabbers[id].enabled) {
|
||||||
//if (!m_grabber_connections[id].model.is_initialized() || !m_grabber_connections[id].old_center.isApprox(center)) {
|
//if (!m_grabber_connections[id].model.is_initialized() || !m_grabber_connections[id].old_center.isApprox(center)) {
|
||||||
m_grabber_connections[id].old_center = center;
|
m_grabber_connections[id].old_center = m_grabbers[id].center;
|
||||||
m_grabber_connections[id].model.reset();
|
m_grabber_connections[id].model.reset();
|
||||||
|
|
||||||
GLModel::Geometry init_data;
|
GLModel::Geometry init_data;
|
||||||
|
@ -166,7 +175,7 @@ void GLGizmoMove3D::on_render()
|
||||||
init_data.reserve_indices(2);
|
init_data.reserve_indices(2);
|
||||||
|
|
||||||
// vertices
|
// vertices
|
||||||
init_data.add_vertex((Vec3f)center.cast<float>());
|
init_data.add_vertex((Vec3f)zero.cast<float>());
|
||||||
init_data.add_vertex((Vec3f)m_grabbers[id].center.cast<float>());
|
init_data.add_vertex((Vec3f)m_grabbers[id].center.cast<float>());
|
||||||
|
|
||||||
// indices
|
// indices
|
||||||
|
@ -186,7 +195,7 @@ void GLGizmoMove3D::on_render()
|
||||||
if (shader != nullptr) {
|
if (shader != nullptr) {
|
||||||
shader->start_using();
|
shader->start_using();
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * base_matrix);
|
||||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||||
|
|
||||||
// draw axes
|
// draw axes
|
||||||
|
@ -199,6 +208,28 @@ void GLGizmoMove3D::on_render()
|
||||||
|
|
||||||
// draw grabbers
|
// draw grabbers
|
||||||
render_grabbers(box);
|
render_grabbers(box);
|
||||||
|
|
||||||
|
if (m_object_manipulation->is_instance_coordinates()) {
|
||||||
|
shader = wxGetApp().get_shader("flat");
|
||||||
|
if (shader != nullptr) {
|
||||||
|
shader->start_using();
|
||||||
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
|
|
||||||
|
Geometry::Transformation cur_tran;
|
||||||
|
if (auto mi = m_parent.get_selection().get_selected_single_intance()) {
|
||||||
|
cur_tran = mi->get_transformation();
|
||||||
|
} else {
|
||||||
|
cur_tran = selection.get_first_volume()->get_instance_transformation();
|
||||||
|
}
|
||||||
|
|
||||||
|
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * cur_tran.get_matrix());
|
||||||
|
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||||
|
|
||||||
|
render_cross_mark(Vec3f::Zero(), true);
|
||||||
|
|
||||||
|
shader->stop_using();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoMove3D::on_register_raycasters_for_picking()
|
void GLGizmoMove3D::on_register_raycasters_for_picking()
|
||||||
|
@ -245,5 +276,30 @@ double GLGizmoMove3D::calc_projection(const UpdateData& data) const
|
||||||
|
|
||||||
return projection;
|
return projection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoMove3D::change_cs_by_selection() {
|
||||||
|
int obejct_idx, volume_idx;
|
||||||
|
ModelVolume *model_volume = m_parent.get_selection().get_selected_single_volume(obejct_idx, volume_idx);
|
||||||
|
if (m_last_selected_obejct_idx == obejct_idx && m_last_selected_volume_idx == volume_idx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_last_selected_obejct_idx = obejct_idx;
|
||||||
|
m_last_selected_volume_idx = volume_idx;
|
||||||
|
if (m_parent.get_selection().is_multiple_full_object()) {
|
||||||
|
m_object_manipulation->set_use_object_cs(false);
|
||||||
|
}
|
||||||
|
else if (model_volume) {
|
||||||
|
m_object_manipulation->set_use_object_cs(true);
|
||||||
|
} else {
|
||||||
|
m_object_manipulation->set_use_object_cs(false);
|
||||||
|
}
|
||||||
|
if (m_object_manipulation->get_use_object_cs()) {
|
||||||
|
m_object_manipulation->set_coordinates_type(ECoordinatesType::Instance);
|
||||||
|
} else {
|
||||||
|
m_object_manipulation->set_coordinates_type(ECoordinatesType::World);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -16,6 +16,8 @@ class GLGizmoMove3D : public GLGizmoBase
|
||||||
static const double Offset;
|
static const double Offset;
|
||||||
|
|
||||||
Vec3d m_displacement{ Vec3d::Zero() };
|
Vec3d m_displacement{ Vec3d::Zero() };
|
||||||
|
Vec3d m_center{ Vec3d::Zero() };
|
||||||
|
BoundingBoxf3 m_bounding_box;
|
||||||
double m_snap_step{ 1.0 };
|
double m_snap_step{ 1.0 };
|
||||||
Vec3d m_starting_drag_position{ Vec3d::Zero() };
|
Vec3d m_starting_drag_position{ Vec3d::Zero() };
|
||||||
Vec3d m_starting_box_center{ Vec3d::Zero() };
|
Vec3d m_starting_box_center{ Vec3d::Zero() };
|
||||||
|
@ -57,6 +59,7 @@ protected:
|
||||||
bool on_init() override;
|
bool on_init() override;
|
||||||
std::string on_get_name() const override;
|
std::string on_get_name() const override;
|
||||||
bool on_is_activable() const override;
|
bool on_is_activable() const override;
|
||||||
|
virtual void on_set_state() override;
|
||||||
void on_start_dragging() override;
|
void on_start_dragging() override;
|
||||||
void on_stop_dragging() override;
|
void on_stop_dragging() override;
|
||||||
void on_dragging(const UpdateData& data) override;
|
void on_dragging(const UpdateData& data) override;
|
||||||
|
@ -68,6 +71,9 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
double calc_projection(const UpdateData& data) const;
|
double calc_projection(const UpdateData& data) const;
|
||||||
|
void change_cs_by_selection(); //cs mean Coordinate System
|
||||||
|
private:
|
||||||
|
int m_last_selected_obejct_idx, m_last_selected_volume_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -527,25 +527,6 @@ bool GLGizmoRotate3D::on_mouse(const wxMouseEvent &mouse_event)
|
||||||
return use_grabbers(mouse_event);
|
return use_grabbers(mouse_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoRotate3D::data_changed(bool is_serializing) {
|
|
||||||
const Selection &selection = m_parent.get_selection();
|
|
||||||
bool is_wipe_tower = selection.is_wipe_tower();
|
|
||||||
if (is_wipe_tower) {
|
|
||||||
DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
|
||||||
float wipe_tower_rotation_angle =
|
|
||||||
dynamic_cast<const ConfigOptionFloat *>(
|
|
||||||
config.option("wipe_tower_rotation_angle"))
|
|
||||||
->value;
|
|
||||||
set_rotation(Vec3d(0., 0., (M_PI / 180.) * wipe_tower_rotation_angle));
|
|
||||||
m_gizmos[0].disable_grabber();
|
|
||||||
m_gizmos[1].disable_grabber();
|
|
||||||
} else {
|
|
||||||
set_rotation(Vec3d::Zero());
|
|
||||||
m_gizmos[0].enable_grabber();
|
|
||||||
m_gizmos[1].enable_grabber();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLGizmoRotate3D::on_init()
|
bool GLGizmoRotate3D::on_init()
|
||||||
{
|
{
|
||||||
for (GLGizmoRotate& g : m_gizmos)
|
for (GLGizmoRotate& g : m_gizmos)
|
||||||
|
@ -561,7 +542,57 @@ bool GLGizmoRotate3D::on_init()
|
||||||
|
|
||||||
std::string GLGizmoRotate3D::on_get_name() const
|
std::string GLGizmoRotate3D::on_get_name() const
|
||||||
{
|
{
|
||||||
return _u8L("Rotate");
|
if (!on_is_activable() && m_state == EState::Off) {
|
||||||
|
return _u8L("Rotate") + ":\n" + _u8L("Please select at least one object.");
|
||||||
|
} else {
|
||||||
|
return _u8L("Rotate");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoRotate3D::on_set_state()
|
||||||
|
{
|
||||||
|
for (GLGizmoRotate &g : m_gizmos)
|
||||||
|
g.set_state(m_state);
|
||||||
|
if (get_state() == On) {
|
||||||
|
m_object_manipulation->set_coordinates_type(ECoordinatesType::World);
|
||||||
|
} else {
|
||||||
|
m_last_volume = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLGizmoRotate3D::data_changed(bool is_serializing) {
|
||||||
|
const Selection &selection = m_parent.get_selection();
|
||||||
|
const GLVolume * volume = selection.get_first_volume();
|
||||||
|
if (volume == nullptr) {
|
||||||
|
m_last_volume = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (m_last_volume != volume) {
|
||||||
|
m_last_volume = volume;
|
||||||
|
Geometry::Transformation tran;
|
||||||
|
if (selection.is_single_full_instance()) {
|
||||||
|
tran = volume->get_instance_transformation();
|
||||||
|
} else {
|
||||||
|
tran = volume->get_volume_transformation();
|
||||||
|
}
|
||||||
|
m_object_manipulation->set_init_rotation(tran);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_wipe_tower = selection.is_wipe_tower();
|
||||||
|
if (is_wipe_tower) {
|
||||||
|
DynamicPrintConfig& config = wxGetApp().preset_bundle->prints.get_edited_preset().config;
|
||||||
|
float wipe_tower_rotation_angle =
|
||||||
|
dynamic_cast<const ConfigOptionFloat *>(
|
||||||
|
config.option("wipe_tower_rotation_angle"))
|
||||||
|
->value;
|
||||||
|
set_rotation(Vec3d(0., 0., (M_PI / 180.) * wipe_tower_rotation_angle));
|
||||||
|
m_gizmos[0].disable_grabber();
|
||||||
|
m_gizmos[1].disable_grabber();
|
||||||
|
} else {
|
||||||
|
set_rotation(Vec3d::Zero());
|
||||||
|
m_gizmos[0].enable_grabber();
|
||||||
|
m_gizmos[1].enable_grabber();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoRotate3D::on_is_activable() const
|
bool GLGizmoRotate3D::on_is_activable() const
|
||||||
|
|
|
@ -151,11 +151,9 @@ public:
|
||||||
protected:
|
protected:
|
||||||
bool on_init() override;
|
bool on_init() override;
|
||||||
std::string on_get_name() const override;
|
std::string on_get_name() const override;
|
||||||
void on_set_state() override {
|
void on_set_state() override;
|
||||||
for (GLGizmoRotate& g : m_gizmos)
|
void on_set_hover_id() override
|
||||||
g.set_state(m_state);
|
{
|
||||||
}
|
|
||||||
void on_set_hover_id() override {
|
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1);
|
m_gizmos[i].set_hover_id((m_hover_id == i) ? 0 : -1);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +177,7 @@ protected:
|
||||||
void on_render_input_window(float x, float y, float bottom_limit) override;
|
void on_render_input_window(float x, float y, float bottom_limit) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const GLVolume *m_last_volume;
|
||||||
class RotoptimzeWindow
|
class RotoptimzeWindow
|
||||||
{
|
{
|
||||||
ImGuiWrapper *m_imgui = nullptr;
|
ImGuiWrapper *m_imgui = nullptr;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
#include <wx/utils.h>
|
#include <wx/utils.h>
|
||||||
|
|
||||||
namespace Slic3r {
|
namespace Slic3r {
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
@ -24,11 +24,11 @@ Vec3d GetIntersectionOfRayAndPlane(Vec3d ray_position, Vec3d ray_dir, Vec3d plan
|
||||||
//BBS: GUI refactor: add obj manipulation
|
//BBS: GUI refactor: add obj manipulation
|
||||||
GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, GizmoObjectManipulation* obj_manipulation)
|
GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filename, unsigned int sprite_id, GizmoObjectManipulation* obj_manipulation)
|
||||||
: GLGizmoBase(parent, icon_filename, sprite_id)
|
: GLGizmoBase(parent, icon_filename, sprite_id)
|
||||||
|
, m_scale(Vec3d::Ones())
|
||||||
|
, m_offset(Vec3d::Zero())
|
||||||
|
, m_snap_step(0.05)
|
||||||
//BBS: GUI refactor: add obj manipulation
|
//BBS: GUI refactor: add obj manipulation
|
||||||
, m_object_manipulation(obj_manipulation)
|
, m_object_manipulation(obj_manipulation)
|
||||||
, m_base_color(DEFAULT_BASE_COLOR)
|
|
||||||
, m_drag_color(DEFAULT_DRAG_COLOR)
|
|
||||||
, m_highlight_color(DEFAULT_HIGHLIGHT_COLOR)
|
|
||||||
{
|
{
|
||||||
m_grabber_connections[0].grabber_indices = { 0, 1 };
|
m_grabber_connections[0].grabber_indices = { 0, 1 };
|
||||||
m_grabber_connections[1].grabber_indices = { 2, 3 };
|
m_grabber_connections[1].grabber_indices = { 2, 3 };
|
||||||
|
@ -39,6 +39,17 @@ GLGizmoScale3D::GLGizmoScale3D(GLCanvas3D& parent, const std::string& icon_filen
|
||||||
m_grabber_connections[6].grabber_indices = { 9, 6 };
|
m_grabber_connections[6].grabber_indices = { 9, 6 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Vec3d &GLGizmoScale3D::get_scale()
|
||||||
|
{
|
||||||
|
if (m_object_manipulation) {
|
||||||
|
Vec3d cache_scale = m_object_manipulation->get_cache().scale.cwiseQuotient(Vec3d(100,100,100));
|
||||||
|
Vec3d temp_scale = cache_scale.cwiseProduct(m_scale);
|
||||||
|
m_object_manipulation->limit_scaling_ratio(temp_scale);
|
||||||
|
m_scale = temp_scale.cwiseQuotient(cache_scale);
|
||||||
|
}
|
||||||
|
return m_scale;
|
||||||
|
}
|
||||||
|
|
||||||
std::string GLGizmoScale3D::get_tooltip() const
|
std::string GLGizmoScale3D::get_tooltip() const
|
||||||
{
|
{
|
||||||
const Selection& selection = m_parent.get_selection();
|
const Selection& selection = m_parent.get_selection();
|
||||||
|
@ -70,77 +81,57 @@ std::string GLGizmoScale3D::get_tooltip() const
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static int constraint_id(int grabber_id)
|
|
||||||
{
|
|
||||||
static const std::vector<int> id_map = { 1, 0, 3, 2, 5, 4, 8, 9, 6, 7 };
|
|
||||||
return (0 <= grabber_id && grabber_id < (int)id_map.size()) ? id_map[grabber_id] : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLGizmoScale3D::on_mouse(const wxMouseEvent &mouse_event)
|
bool GLGizmoScale3D::on_mouse(const wxMouseEvent &mouse_event)
|
||||||
{
|
{
|
||||||
if (mouse_event.Dragging()) {
|
if (mouse_event.Dragging()) {
|
||||||
if (m_dragging) {
|
if (m_dragging) {
|
||||||
// Apply new temporary scale factors
|
// Apply new temporary scale factors
|
||||||
Selection& selection = m_parent.get_selection();
|
|
||||||
TransformationType transformation_type;
|
TransformationType transformation_type;
|
||||||
if (selection.is_single_full_instance()) {
|
if (wxGetApp().obj_manipul()->is_local_coordinates())
|
||||||
transformation_type.set_instance();
|
|
||||||
} else if (selection.is_single_volume_or_modifier()) {
|
|
||||||
transformation_type.set_local();
|
transformation_type.set_local();
|
||||||
}
|
else if (wxGetApp().obj_manipul()->is_instance_coordinates())
|
||||||
|
transformation_type.set_instance();
|
||||||
|
|
||||||
transformation_type.set_relative();
|
transformation_type.set_relative();
|
||||||
|
|
||||||
if (mouse_event.AltDown())
|
if (mouse_event.AltDown())
|
||||||
transformation_type.set_independent();
|
transformation_type.set_independent();
|
||||||
|
|
||||||
selection.scale(m_scale, transformation_type);
|
Selection& selection = m_parent.get_selection();
|
||||||
if (m_starting.ctrl_down && m_hover_id < 6) {
|
selection.scale_and_translate(get_scale(), get_offset(), transformation_type);
|
||||||
// constrained scale:
|
|
||||||
// uses the performed scale to calculate the new position of the constrained grabber
|
|
||||||
// and from that calculates the offset (in world coordinates) to be applied to fullfill the constraint
|
|
||||||
update_render_data();
|
|
||||||
const Vec3d constraint_position = m_grabbers[constraint_id(m_hover_id)].center;
|
|
||||||
// re-apply the scale because the selection always applies the transformations with respect to the initial state
|
|
||||||
// set into on_start_dragging() with the call to selection.setup_cache()
|
|
||||||
m_parent.get_selection().scale_and_translate(m_scale, m_starting.pivots[m_hover_id] - constraint_position, transformation_type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return use_grabbers(mouse_event);
|
return use_grabbers(mouse_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoScale3D::data_changed(bool is_serializing)
|
||||||
|
{
|
||||||
|
const Selection &selection = m_parent.get_selection();
|
||||||
|
bool enable_scale_xyz = selection.is_single_full_instance() ||
|
||||||
|
selection.is_single_volume_or_modifier();
|
||||||
|
for (unsigned int i = 0; i < 6; ++i)
|
||||||
|
m_grabbers[i].enabled = enable_scale_xyz;
|
||||||
|
|
||||||
|
set_scale(Vec3d::Ones());
|
||||||
|
|
||||||
|
change_cs_by_selection();
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoScale3D::enable_ununiversal_scale(bool enable)
|
void GLGizmoScale3D::enable_ununiversal_scale(bool enable)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < 6; ++i)
|
for (unsigned int i = 0; i < 6; ++i)
|
||||||
m_grabbers[i].enabled = enable;
|
m_grabbers[i].enabled = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoScale3D::data_changed(bool is_serializing) {
|
|
||||||
const Selection &selection = m_parent.get_selection();
|
|
||||||
bool enable_scale_xyz = selection.is_single_full_instance() ||
|
|
||||||
selection.is_single_volume_or_modifier();
|
|
||||||
for (unsigned int i = 0; i < 6; ++i)
|
|
||||||
m_grabbers[i].enabled = enable_scale_xyz;
|
|
||||||
|
|
||||||
set_scale(Vec3d::Ones());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLGizmoScale3D::on_init()
|
bool GLGizmoScale3D::on_init()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 10; ++i) {
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
m_grabbers.push_back(Grabber());
|
m_grabbers.push_back(Grabber());
|
||||||
}
|
}
|
||||||
|
|
||||||
double half_pi = 0.5 * (double)PI;
|
double half_pi = 0.5 * (double)PI;
|
||||||
|
|
||||||
// x axis
|
|
||||||
m_grabbers[0].angles(1) = half_pi;
|
|
||||||
m_grabbers[1].angles(1) = half_pi;
|
|
||||||
|
|
||||||
// y axis
|
|
||||||
m_grabbers[2].angles(0) = half_pi;
|
|
||||||
m_grabbers[3].angles(0) = half_pi;
|
|
||||||
|
|
||||||
// BBS
|
// BBS
|
||||||
m_grabbers[4].enabled = false;
|
m_grabbers[4].enabled = false;
|
||||||
|
@ -151,7 +142,11 @@ bool GLGizmoScale3D::on_init()
|
||||||
|
|
||||||
std::string GLGizmoScale3D::on_get_name() const
|
std::string GLGizmoScale3D::on_get_name() const
|
||||||
{
|
{
|
||||||
return _u8L("Scale");
|
if (!on_is_activable() && m_state == EState::Off) {
|
||||||
|
return _u8L("Scale") + ":\n" + _u8L("Please select at least one object.");
|
||||||
|
} else {
|
||||||
|
return _u8L("Scale");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmoScale3D::on_is_activable() const
|
bool GLGizmoScale3D::on_is_activable() const
|
||||||
|
@ -160,21 +155,48 @@ bool GLGizmoScale3D::on_is_activable() const
|
||||||
return !selection.is_empty() && !selection.is_wipe_tower();
|
return !selection.is_empty() && !selection.is_wipe_tower();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoScale3D::on_set_state() {
|
||||||
|
if (get_state() == On) {
|
||||||
|
m_last_selected_obejct_idx = -1;
|
||||||
|
m_last_selected_volume_idx = -1;
|
||||||
|
change_cs_by_selection();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int constraint_id(int grabber_id)
|
||||||
|
{
|
||||||
|
static const std::vector<int> id_map = {1, 0, 3, 2, 5, 4, 8, 9, 6, 7};
|
||||||
|
return (0 <= grabber_id && grabber_id < (int) id_map.size()) ? id_map[grabber_id] : -1;
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoScale3D::on_start_dragging()
|
void GLGizmoScale3D::on_start_dragging()
|
||||||
{
|
{
|
||||||
assert(m_hover_id != -1);
|
if (m_hover_id != -1) {
|
||||||
m_starting.drag_position = m_grabbers[m_hover_id].center;
|
auto grabbers_transform = m_grabbers_tran.get_matrix();
|
||||||
m_starting.plane_center = m_grabbers[4].center;
|
m_starting.drag_position = grabbers_transform * m_grabbers[m_hover_id].center;
|
||||||
m_starting.plane_nromal = m_grabbers[5].center - m_grabbers[4].center;
|
m_starting.plane_center = grabbers_transform * m_grabbers[4].center; // plane_center = bottom center
|
||||||
m_starting.ctrl_down = wxGetKeyState(WXK_CONTROL);
|
m_starting.plane_nromal = (grabbers_transform * m_grabbers[5].center - grabbers_transform * m_grabbers[4].center).normalized();
|
||||||
m_starting.box = m_box;
|
m_starting.ctrl_down = wxGetKeyState(WXK_CONTROL);
|
||||||
|
m_starting.box = m_bounding_box;
|
||||||
|
|
||||||
m_starting.pivots[0] = m_grabbers[1].center;
|
m_starting.center = m_center;
|
||||||
m_starting.pivots[1] = m_grabbers[0].center;
|
m_starting.instance_center = m_instance_center;
|
||||||
m_starting.pivots[2] = m_grabbers[3].center;
|
|
||||||
m_starting.pivots[3] = m_grabbers[2].center;
|
const Vec3d box_half_size = 0.5 * m_bounding_box.size();
|
||||||
m_starting.pivots[4] = m_grabbers[5].center;
|
|
||||||
m_starting.pivots[5] = m_grabbers[4].center;
|
m_starting.local_pivots[0] = Vec3d(box_half_size.x(), 0.0, -box_half_size.z());
|
||||||
|
m_starting.local_pivots[1] = Vec3d(-box_half_size.x(), 0.0, -box_half_size.z());
|
||||||
|
m_starting.local_pivots[2] = Vec3d(0.0, box_half_size.y(), -box_half_size.z());
|
||||||
|
m_starting.local_pivots[3] = Vec3d(0.0, -box_half_size.y(), -box_half_size.z());
|
||||||
|
m_starting.local_pivots[4] = Vec3d(0.0, 0.0, box_half_size.z());
|
||||||
|
m_starting.local_pivots[5] = Vec3d(0.0, 0.0, -box_half_size.z());
|
||||||
|
for (size_t i = 0; i < 6; i++) {
|
||||||
|
m_starting.pivots[i] = grabbers_transform * m_starting.local_pivots[i]; // todo delete
|
||||||
|
}
|
||||||
|
m_starting.constraint_position = grabbers_transform * m_grabbers[constraint_id(m_hover_id)].center;
|
||||||
|
m_scale = m_starting.scale = Vec3d::Ones() ;
|
||||||
|
m_offset = Vec3d::Zero();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoScale3D::on_stop_dragging()
|
void GLGizmoScale3D::on_stop_dragging()
|
||||||
|
@ -185,26 +207,95 @@ void GLGizmoScale3D::on_stop_dragging()
|
||||||
|
|
||||||
void GLGizmoScale3D::on_dragging(const UpdateData& data)
|
void GLGizmoScale3D::on_dragging(const UpdateData& data)
|
||||||
{
|
{
|
||||||
if (m_hover_id == 0 || m_hover_id == 1)
|
if ((m_hover_id == 0) || (m_hover_id == 1))
|
||||||
do_scale_along_axis(X, data);
|
do_scale_along_axis(X, data);
|
||||||
else if (m_hover_id == 2 || m_hover_id == 3)
|
else if ((m_hover_id == 2) || (m_hover_id == 3))
|
||||||
do_scale_along_axis(Y, data);
|
do_scale_along_axis(Y, data);
|
||||||
else if (m_hover_id == 4 || m_hover_id == 5)
|
else if ((m_hover_id == 4) || (m_hover_id == 5))
|
||||||
do_scale_along_axis(Z, data);
|
do_scale_along_axis(Z, data);
|
||||||
else if (m_hover_id >= 6)
|
else if (m_hover_id >= 6)
|
||||||
do_scale_uniform(data);
|
do_scale_uniform(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLGizmoScale3D::update_grabbers_data()
|
||||||
|
{
|
||||||
|
const Selection &selection = m_parent.get_selection();
|
||||||
|
const auto &[box, box_trafo] = selection.get_bounding_box_in_current_reference_system();
|
||||||
|
m_bounding_box = box;
|
||||||
|
m_center = box_trafo.translation();
|
||||||
|
m_grabbers_tran.set_matrix(box_trafo);
|
||||||
|
m_instance_center = (selection.is_single_full_instance() || selection.is_single_volume_or_modifier()) ? selection.get_first_volume()->get_instance_offset() : m_center;
|
||||||
|
|
||||||
|
const Vec3d box_half_size = 0.5 * m_bounding_box.size();
|
||||||
|
bool ctrl_down = wxGetKeyState(WXK_CONTROL);
|
||||||
|
|
||||||
|
|
||||||
|
bool single_instance = selection.is_single_full_instance();
|
||||||
|
bool single_volume = selection.is_single_modifier() || selection.is_single_volume();
|
||||||
|
|
||||||
|
// x axis
|
||||||
|
m_grabbers[0].center = Vec3d(-(box_half_size.x()), 0.0, -box_half_size.z());
|
||||||
|
m_grabbers[0].color = (ctrl_down && m_hover_id == 1) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||||
|
m_grabbers[1].center = Vec3d(box_half_size.x(), 0.0, -box_half_size.z());
|
||||||
|
m_grabbers[1].color = (ctrl_down && m_hover_id == 0) ? CONSTRAINED_COLOR : AXES_COLOR[0];
|
||||||
|
// y axis
|
||||||
|
m_grabbers[2].center = Vec3d(0.0, -(box_half_size.y()), -box_half_size.z());
|
||||||
|
m_grabbers[2].color = (ctrl_down && m_hover_id == 3) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||||
|
m_grabbers[3].center = Vec3d(0.0, box_half_size.y(), -box_half_size.z());
|
||||||
|
m_grabbers[3].color = (ctrl_down && m_hover_id == 2) ? CONSTRAINED_COLOR : AXES_COLOR[1];
|
||||||
|
// z axis do not show 4
|
||||||
|
m_grabbers[4].center = Vec3d(0.0, 0.0, -(box_half_size.z()));
|
||||||
|
m_grabbers[4].enabled = false;
|
||||||
|
|
||||||
|
m_grabbers[5].center = Vec3d(0.0, 0.0, box_half_size.z());
|
||||||
|
m_grabbers[5].color = (ctrl_down && m_hover_id == 4) ? CONSTRAINED_COLOR : AXES_COLOR[2];
|
||||||
|
// uniform
|
||||||
|
m_grabbers[6].center = Vec3d(-box_half_size.x(), -box_half_size.y(), -box_half_size.z());
|
||||||
|
m_grabbers[6].color = (ctrl_down && m_hover_id == 8) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||||
|
m_grabbers[7].center = Vec3d(box_half_size.x(), -box_half_size.y(), -box_half_size.z());
|
||||||
|
m_grabbers[7].color = (ctrl_down && m_hover_id == 9) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||||
|
m_grabbers[8].center = Vec3d(box_half_size.x(), box_half_size.y(), -box_half_size.z());
|
||||||
|
m_grabbers[8].color = (ctrl_down && m_hover_id == 6) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||||
|
m_grabbers[9].center = Vec3d(-box_half_size.x(), box_half_size.y(), -box_half_size.z());
|
||||||
|
m_grabbers[9].color = (ctrl_down && m_hover_id == 7) ? CONSTRAINED_COLOR : GRABBER_UNIFORM_COL;
|
||||||
|
for (int i = 0; i < 6; ++i) {
|
||||||
|
//m_grabbers[i].color = AXES_COLOR[i / 2];
|
||||||
|
m_grabbers[i].hover_color = AXES_HOVER_COLOR[i / 2];
|
||||||
|
}
|
||||||
|
for (int i = 6; i < 10; ++i) {
|
||||||
|
//m_grabbers[i].color = GRABBER_UNIFORM_COL;
|
||||||
|
m_grabbers[i].hover_color = GRABBER_UNIFORM_HOVER_COL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
m_grabbers[i].matrix = m_grabbers_tran.get_matrix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GLGizmoScale3D::change_cs_by_selection() {
|
||||||
|
int obejct_idx, volume_idx;
|
||||||
|
ModelVolume *model_volume = m_parent.get_selection().get_selected_single_volume(obejct_idx, volume_idx);
|
||||||
|
if (m_last_selected_obejct_idx == obejct_idx && m_last_selected_volume_idx == volume_idx) { return; }
|
||||||
|
m_last_selected_obejct_idx = obejct_idx;
|
||||||
|
m_last_selected_volume_idx = volume_idx;
|
||||||
|
if (m_parent.get_selection().is_multiple_full_object()) {
|
||||||
|
m_object_manipulation->set_coordinates_type(ECoordinatesType::World);
|
||||||
|
} else if (model_volume) {
|
||||||
|
m_object_manipulation->set_coordinates_type(ECoordinatesType::Local);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void GLGizmoScale3D::on_render()
|
void GLGizmoScale3D::on_render()
|
||||||
{
|
{
|
||||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
update_render_data();
|
update_grabbers_data();
|
||||||
|
|
||||||
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
|
glsafe(::glLineWidth((m_hover_id != -1) ? 2.0f : 1.5f));
|
||||||
|
|
||||||
const float grabber_mean_size = (float) ((m_box.size().x() + m_box.size().y() + m_box.size().z()) / 3.0);
|
const float grabber_mean_size = (float)((m_bounding_box.size().x() + m_bounding_box.size().y() + m_bounding_box.size().z()) / 3.0);
|
||||||
|
|
||||||
//draw connections
|
//draw connections
|
||||||
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
GLShaderProgram* shader = wxGetApp().get_shader("flat");
|
||||||
|
@ -213,7 +304,7 @@ void GLGizmoScale3D::on_render()
|
||||||
// BBS: when select multiple objects, uniform scale can be deselected, display the connection(4,5)
|
// BBS: when select multiple objects, uniform scale can be deselected, display the connection(4,5)
|
||||||
//if (single_instance || single_volume) {
|
//if (single_instance || single_volume) {
|
||||||
const Camera& camera = wxGetApp().plater()->get_camera();
|
const Camera& camera = wxGetApp().plater()->get_camera();
|
||||||
shader->set_uniform("view_model_matrix", camera.get_view_matrix());
|
shader->set_uniform("view_model_matrix", camera.get_view_matrix() * m_grabbers_tran.get_matrix());
|
||||||
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
shader->set_uniform("projection_matrix", camera.get_projection_matrix());
|
||||||
if (m_grabbers[4].enabled && m_grabbers[5].enabled)
|
if (m_grabbers[4].enabled && m_grabbers[5].enabled)
|
||||||
render_grabbers_connection(4, 5, m_grabbers[4].color);
|
render_grabbers_connection(4, 5, m_grabbers[4].color);
|
||||||
|
@ -298,29 +389,53 @@ void GLGizmoScale3D::on_render_input_window(float x, float y, float bottom_limit
|
||||||
void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
|
void GLGizmoScale3D::do_scale_along_axis(Axis axis, const UpdateData& data)
|
||||||
{
|
{
|
||||||
double ratio = calc_ratio(data);
|
double ratio = calc_ratio(data);
|
||||||
if (ratio > 0.0) {
|
if (ratio > 0.0)
|
||||||
Vec3d curr_scale = m_scale;
|
{
|
||||||
curr_scale(axis) = m_starting.scale(axis) * ratio;
|
m_scale(axis) = m_starting.scale(axis) * ratio;
|
||||||
m_scale = curr_scale;
|
if (m_starting.ctrl_down && abs(ratio-1.0f)>0.001) {
|
||||||
|
double local_offset = 0.5 * (m_scale(axis) - m_starting.scale(axis)) * m_starting.box.size()(axis);
|
||||||
|
if (m_hover_id == 2 * axis) {
|
||||||
|
local_offset *= -1.0;
|
||||||
|
}
|
||||||
|
Vec3d local_offset_vec;
|
||||||
|
switch (axis)
|
||||||
|
{
|
||||||
|
case X: { local_offset_vec = local_offset * Vec3d::UnitX(); break; }
|
||||||
|
case Y: { local_offset_vec = local_offset * Vec3d::UnitY(); break;}
|
||||||
|
case Z: { local_offset_vec = local_offset * Vec3d::UnitZ(); break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (m_object_manipulation->is_world_coordinates()) {
|
||||||
|
m_offset = local_offset_vec;
|
||||||
|
} else {//if (m_object_manipulation->is_instance_coordinates())
|
||||||
|
m_offset = m_grabbers_tran.get_matrix_no_offset() * local_offset_vec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_offset = Vec3d::Zero();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoScale3D::do_scale_uniform(const UpdateData & data)
|
void GLGizmoScale3D::do_scale_uniform(const UpdateData& data)
|
||||||
{
|
{
|
||||||
const double ratio = calc_ratio(data);
|
double ratio = calc_ratio(data);
|
||||||
if (ratio > 0.0)
|
if (ratio > 0.0)
|
||||||
|
{
|
||||||
m_scale = m_starting.scale * ratio;
|
m_scale = m_starting.scale * ratio;
|
||||||
|
m_offset = Vec3d::Zero();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
|
double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
|
||||||
{
|
{
|
||||||
double ratio = 0.0;
|
double ratio = 0.0;
|
||||||
|
|
||||||
Vec3d pivot = (m_starting.ctrl_down && m_hover_id < 6) ? m_starting.pivots[m_hover_id] : m_starting.plane_center;
|
Vec3d pivot = (m_starting.ctrl_down && (m_hover_id < 6)) ? m_starting.constraint_position : m_starting.plane_center; // plane_center = bottom center
|
||||||
|
|
||||||
Vec3d starting_vec = m_starting.drag_position - pivot;
|
Vec3d starting_vec = m_starting.drag_position - pivot;
|
||||||
double len_starting_vec = starting_vec.norm();
|
double len_starting_vec = starting_vec.norm();
|
||||||
if (len_starting_vec != 0.0) {
|
if (len_starting_vec != 0.0)
|
||||||
|
{
|
||||||
Vec3d mouse_dir = data.mouse_ray.unit_vector();
|
Vec3d mouse_dir = data.mouse_ray.unit_vector();
|
||||||
Vec3d plane_normal = m_starting.plane_nromal;
|
Vec3d plane_normal = m_starting.plane_nromal;
|
||||||
if (m_hover_id == 5) {
|
if (m_hover_id == 5) {
|
||||||
|
@ -328,10 +443,16 @@ double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
|
||||||
Vec3d plane_vec = mouse_dir.cross(m_starting.plane_nromal);
|
Vec3d plane_vec = mouse_dir.cross(m_starting.plane_nromal);
|
||||||
plane_normal = plane_vec.cross(m_starting.plane_nromal);
|
plane_normal = plane_vec.cross(m_starting.plane_nromal);
|
||||||
}
|
}
|
||||||
|
plane_normal = plane_normal.normalized();
|
||||||
// finds the intersection of the mouse ray with the plane that the drag point moves
|
// finds the intersection of the mouse ray with the plane that the drag point moves
|
||||||
// use ray-plane intersection see i.e. https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection
|
// use ray-plane intersection see i.e. https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection
|
||||||
Vec3d inters = GetIntersectionOfRayAndPlane(data.mouse_ray.a, mouse_dir, m_starting.drag_position, plane_normal.normalized());
|
auto dot_value = (plane_normal.dot(mouse_dir));
|
||||||
|
auto angle = Geometry::rad2deg(acos(dot_value));
|
||||||
|
auto big_than_min_angle = abs(angle) < 95 && abs(angle) > 85;
|
||||||
|
if (big_than_min_angle) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
Vec3d inters = GetIntersectionOfRayAndPlane(data.mouse_ray.a, mouse_dir, m_starting.drag_position, plane_normal);
|
||||||
|
|
||||||
Vec3d inters_vec = inters - m_starting.drag_position;
|
Vec3d inters_vec = inters - m_starting.drag_position;
|
||||||
|
|
||||||
|
@ -347,78 +468,5 @@ double GLGizmoScale3D::calc_ratio(const UpdateData& data) const
|
||||||
return ratio;
|
return ratio;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLGizmoScale3D::update_render_data()
|
|
||||||
{
|
|
||||||
|
|
||||||
const Selection& selection = m_parent.get_selection();
|
|
||||||
|
|
||||||
bool single_instance = selection.is_single_full_instance();
|
|
||||||
bool single_volume = selection.is_single_volume_or_modifier();
|
|
||||||
|
|
||||||
m_box.reset();
|
|
||||||
m_transform = Transform3d::Identity();
|
|
||||||
Vec3d angles = Vec3d::Zero();
|
|
||||||
|
|
||||||
if (single_instance) {
|
|
||||||
// calculate bounding box in instance local reference system
|
|
||||||
const Selection::IndicesList& idxs = selection.get_volume_idxs();
|
|
||||||
for (unsigned int idx : idxs) {
|
|
||||||
const GLVolume* vol = selection.get_volume(idx);
|
|
||||||
m_box.merge(vol->bounding_box().transformed(vol->get_volume_transformation().get_matrix()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// gets transform from first selected volume
|
|
||||||
const GLVolume* v = selection.get_first_volume();
|
|
||||||
m_transform = v->get_instance_transformation().get_matrix();
|
|
||||||
// gets angles from first selected volume
|
|
||||||
angles = v->get_instance_rotation();
|
|
||||||
}
|
|
||||||
else if (single_volume) {
|
|
||||||
const GLVolume* v = selection.get_first_volume();
|
|
||||||
m_box = v->bounding_box();
|
|
||||||
m_transform = v->world_matrix();
|
|
||||||
angles = Geometry::extract_euler_angles(m_transform);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_box = selection.get_bounding_box();
|
|
||||||
|
|
||||||
const Vec3d& center = m_box.center();
|
|
||||||
|
|
||||||
// x axis
|
|
||||||
m_grabbers[0].center = m_transform * Vec3d(m_box.min.x(), center.y(), m_box.min.z());
|
|
||||||
m_grabbers[1].center = m_transform * Vec3d(m_box.max.x(), center.y(), m_box.min.z());
|
|
||||||
|
|
||||||
// y axis
|
|
||||||
m_grabbers[2].center = m_transform * Vec3d(center.x(), m_box.min.y(), m_box.min.z());
|
|
||||||
m_grabbers[3].center = m_transform * Vec3d(center.x(), m_box.max.y(), m_box.min.z());
|
|
||||||
|
|
||||||
// z axis do not show 4
|
|
||||||
m_grabbers[4].center = m_transform * Vec3d(center.x(), center.y(), m_box.min.z());
|
|
||||||
m_grabbers[4].enabled = false;
|
|
||||||
|
|
||||||
m_grabbers[5].center = m_transform * Vec3d(center.x(), center.y(), m_box.max.z());
|
|
||||||
|
|
||||||
// uniform
|
|
||||||
m_grabbers[6].center = m_transform * Vec3d(m_box.min.x(), m_box.min.y(), m_box.min.z());
|
|
||||||
m_grabbers[7].center = m_transform * Vec3d(m_box.max.x(), m_box.min.y(), m_box.min.z());
|
|
||||||
m_grabbers[8].center = m_transform * Vec3d(m_box.max.x(), m_box.max.y(), m_box.min.z());
|
|
||||||
m_grabbers[9].center = m_transform * Vec3d(m_box.min.x(), m_box.max.y(), m_box.min.z());
|
|
||||||
|
|
||||||
for (int i = 0; i < 6; ++i) {
|
|
||||||
m_grabbers[i].color = AXES_COLOR[i/2];
|
|
||||||
m_grabbers[i].hover_color = AXES_HOVER_COLOR[i/2];
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 6; i < 10; ++i) {
|
|
||||||
m_grabbers[i].color = GRABBER_UNIFORM_COL;
|
|
||||||
m_grabbers[i].hover_color = GRABBER_UNIFORM_HOVER_COL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sets grabbers orientation
|
|
||||||
for (int i = 0; i < 10; ++i) {
|
|
||||||
m_grabbers[i].angles = angles;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace GUI
|
} // namespace GUI
|
||||||
} // namespace Slic3r
|
} // namespace Slic3r
|
||||||
|
|
|
@ -19,25 +19,28 @@ class GLGizmoScale3D : public GLGizmoBase
|
||||||
{
|
{
|
||||||
Vec3d scale;
|
Vec3d scale;
|
||||||
Vec3d drag_position;
|
Vec3d drag_position;
|
||||||
|
Vec3d constraint_position;
|
||||||
|
Vec3d center{Vec3d::Zero()};//sphere bounding box center
|
||||||
|
Vec3d instance_center{Vec3d::Zero()};
|
||||||
Vec3d plane_center; // keep the relative center position for scale in the bottom plane
|
Vec3d plane_center; // keep the relative center position for scale in the bottom plane
|
||||||
Vec3d plane_nromal; // keep the bottom plane
|
Vec3d plane_nromal; // keep the bottom plane
|
||||||
BoundingBoxf3 box;
|
BoundingBoxf3 box;
|
||||||
Vec3d pivots[6];
|
Vec3d pivots[6];// Vec3d constraint_position{Vec3d::Zero()};
|
||||||
|
Vec3d local_pivots[6];
|
||||||
bool ctrl_down;
|
bool ctrl_down;
|
||||||
|
|
||||||
StartingData() : scale(Vec3d::Ones()), drag_position(Vec3d::Zero()), ctrl_down(false) { for (int i = 0; i < 5; ++i) { pivots[i] = Vec3d::Zero(); } }
|
StartingData() : scale(Vec3d::Ones()), drag_position(Vec3d::Zero()), ctrl_down(false) { for (int i = 0; i < 5; ++i) { pivots[i] = Vec3d::Zero(); } }
|
||||||
};
|
};
|
||||||
|
|
||||||
BoundingBoxf3 m_box;
|
mutable BoundingBoxf3 m_bounding_box;
|
||||||
Transform3d m_transform;
|
Geometry::Transformation m_grabbers_tran;//m_grabbers_transform
|
||||||
Vec3d m_scale{ Vec3d::Ones() };
|
Vec3d m_center{Vec3d::Zero()};
|
||||||
double m_snap_step{ 0.05 };
|
Vec3d m_instance_center{Vec3d::Zero()};
|
||||||
|
Vec3d m_scale;
|
||||||
|
Vec3d m_offset;
|
||||||
|
double m_snap_step;
|
||||||
StartingData m_starting;
|
StartingData m_starting;
|
||||||
|
|
||||||
ColorRGBA m_base_color;
|
|
||||||
ColorRGBA m_drag_color;
|
|
||||||
ColorRGBA m_highlight_color;
|
|
||||||
|
|
||||||
struct GrabberConnection
|
struct GrabberConnection
|
||||||
{
|
{
|
||||||
GLModel model;
|
GLModel model;
|
||||||
|
@ -58,9 +61,11 @@ public:
|
||||||
double get_snap_step(double step) const { return m_snap_step; }
|
double get_snap_step(double step) const { return m_snap_step; }
|
||||||
void set_snap_step(double step) { m_snap_step = step; }
|
void set_snap_step(double step) { m_snap_step = step; }
|
||||||
|
|
||||||
const Vec3d& get_scale() const { return m_scale; }
|
const Vec3d &get_scale();
|
||||||
void set_scale(const Vec3d& scale) { m_starting.scale = scale; m_scale = scale; }
|
void set_scale(const Vec3d& scale) { m_starting.scale = scale; m_scale = scale; }
|
||||||
|
|
||||||
|
const Vec3d& get_offset() const { return m_offset; }
|
||||||
|
|
||||||
std::string get_tooltip() const override;
|
std::string get_tooltip() const override;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -76,6 +81,7 @@ protected:
|
||||||
virtual bool on_init() override;
|
virtual bool on_init() override;
|
||||||
virtual std::string on_get_name() const override;
|
virtual std::string on_get_name() const override;
|
||||||
virtual bool on_is_activable() const override;
|
virtual bool on_is_activable() const override;
|
||||||
|
virtual void on_set_state() override;
|
||||||
virtual void on_start_dragging() override;
|
virtual void on_start_dragging() override;
|
||||||
virtual void on_stop_dragging() override;
|
virtual void on_stop_dragging() override;
|
||||||
virtual void on_dragging(const UpdateData& data) override;
|
virtual void on_dragging(const UpdateData& data) override;
|
||||||
|
@ -92,7 +98,10 @@ private:
|
||||||
void do_scale_uniform(const UpdateData& data);
|
void do_scale_uniform(const UpdateData& data);
|
||||||
|
|
||||||
double calc_ratio(const UpdateData& data) const;
|
double calc_ratio(const UpdateData& data) const;
|
||||||
void update_render_data();
|
void update_grabbers_data();
|
||||||
|
void change_cs_by_selection(); // cs mean Coordinate System
|
||||||
|
private:
|
||||||
|
int m_last_selected_obejct_idx, m_last_selected_volume_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1024,20 +1024,6 @@ void GLGizmoText::show_tooltip_information(float x, float y)
|
||||||
ImGui::PopStyleVar(2);
|
ImGui::PopStyleVar(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelVolume *GLGizmoText::get_selected_single_volume(int &out_object_idx, int &out_volume_idx) const
|
|
||||||
{
|
|
||||||
if (m_parent.get_selection().is_single_volume() || m_parent.get_selection().is_single_modifier()) {
|
|
||||||
const Selection &selection = m_parent.get_selection();
|
|
||||||
const GLVolume * gl_volume = selection.get_first_volume();
|
|
||||||
out_object_idx = gl_volume->object_idx();
|
|
||||||
ModelObject *model_object = selection.get_model()->objects[out_object_idx];
|
|
||||||
out_volume_idx = gl_volume->volume_idx();
|
|
||||||
if (out_volume_idx < model_object->volumes.size())
|
|
||||||
return model_object->volumes[out_volume_idx];
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLGizmoText::reset_text_info()
|
void GLGizmoText::reset_text_info()
|
||||||
{
|
{
|
||||||
m_font_name = "";
|
m_font_name = "";
|
||||||
|
|
|
@ -62,7 +62,9 @@ std::vector<size_t> GLGizmosManager::get_selectable_idxs() const
|
||||||
out.reserve(m_gizmos.size());
|
out.reserve(m_gizmos.size());
|
||||||
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
if (m_parent.get_canvas_type() == GLCanvas3D::CanvasAssembleView) {
|
||||||
for (size_t i = 0; i < m_gizmos.size(); ++i)
|
for (size_t i = 0; i < m_gizmos.size(); ++i)
|
||||||
if (m_gizmos[i]->get_sprite_id() == (unsigned int) Measure ||
|
if (m_gizmos[i]->get_sprite_id() == (unsigned int) Move ||
|
||||||
|
m_gizmos[i]->get_sprite_id() == (unsigned int) Rotate ||
|
||||||
|
m_gizmos[i]->get_sprite_id() == (unsigned int) Measure ||
|
||||||
m_gizmos[i]->get_sprite_id() == (unsigned int) Assembly ||
|
m_gizmos[i]->get_sprite_id() == (unsigned int) Assembly ||
|
||||||
m_gizmos[i]->get_sprite_id() == (unsigned int) MmuSegmentation)
|
m_gizmos[i]->get_sprite_id() == (unsigned int) MmuSegmentation)
|
||||||
out.push_back(i);
|
out.push_back(i);
|
||||||
|
@ -247,6 +249,16 @@ bool GLGizmosManager::init_icon_textures()
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/toolbar_reset_zero.svg", 14, 14, texture_id))
|
||||||
|
icon_list.insert(std::make_pair((int) IC_TOOLBAR_RESET_ZERO, texture_id));
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/toolbar_reset_zero_hover.svg", 14, 14, texture_id))
|
||||||
|
icon_list.insert(std::make_pair((int) IC_TOOLBAR_RESET_ZERO_HOVER, texture_id));
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/toolbar_tooltip.svg", 25, 25, texture_id)) // ORCA: Use same resolution with gizmos to prevent blur on icon
|
if (IMTexture::load_from_svg_file(Slic3r::resources_dir() + "/images/toolbar_tooltip.svg", 25, 25, texture_id)) // ORCA: Use same resolution with gizmos to prevent blur on icon
|
||||||
icon_list.insert(std::make_pair((int)IC_TOOLBAR_TOOLTIP, texture_id));
|
icon_list.insert(std::make_pair((int)IC_TOOLBAR_TOOLTIP, texture_id));
|
||||||
else
|
else
|
||||||
|
@ -371,6 +383,9 @@ void GLGizmosManager::update_assemble_view_data()
|
||||||
void GLGizmosManager::update_data()
|
void GLGizmosManager::update_data()
|
||||||
{
|
{
|
||||||
if (!m_enabled) return;
|
if (!m_enabled) return;
|
||||||
|
|
||||||
|
const Selection& selection = m_parent.get_selection();
|
||||||
|
|
||||||
if (m_common_gizmos_data)
|
if (m_common_gizmos_data)
|
||||||
m_common_gizmos_data->update(get_current()
|
m_common_gizmos_data->update(get_current()
|
||||||
? get_current()->get_requirements()
|
? get_current()->get_requirements()
|
||||||
|
@ -381,8 +396,10 @@ void GLGizmosManager::update_data()
|
||||||
if (m_current != Flatten && !m_gizmos.empty()) m_gizmos[Flatten]->data_changed(m_serializing);
|
if (m_current != Flatten && !m_gizmos.empty()) m_gizmos[Flatten]->data_changed(m_serializing);
|
||||||
|
|
||||||
//BBS: GUI refactor: add object manipulation in gizmo
|
//BBS: GUI refactor: add object manipulation in gizmo
|
||||||
m_object_manipulation.update_ui_from_settings();
|
if (!selection.is_empty()) {
|
||||||
m_object_manipulation.UpdateAndShow(true);
|
m_object_manipulation.update_ui_from_settings();
|
||||||
|
m_object_manipulation.UpdateAndShow(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLGizmosManager::is_running() const
|
bool GLGizmosManager::is_running() const
|
||||||
|
@ -461,6 +478,22 @@ bool GLGizmosManager::gizmo_event(SLAGizmoEventType action, const Vec2d& mouse_p
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GLGizmosManager::is_paint_gizmo()
|
||||||
|
{
|
||||||
|
return m_current == EType::FdmSupports ||
|
||||||
|
m_current == EType::MmuSegmentation ||
|
||||||
|
m_current == EType::Seam;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLGizmosManager::is_allow_select_all() {
|
||||||
|
if (m_current == Undefined || m_current == EType::Move||
|
||||||
|
m_current == EType::Rotate ||
|
||||||
|
m_current == EType::Scale) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ClippingPlane GLGizmosManager::get_clipping_plane() const
|
ClippingPlane GLGizmosManager::get_clipping_plane() const
|
||||||
{
|
{
|
||||||
if (! m_common_gizmos_data
|
if (! m_common_gizmos_data
|
||||||
|
|
|
@ -164,6 +164,8 @@ public:
|
||||||
enum MENU_ICON_NAME {
|
enum MENU_ICON_NAME {
|
||||||
IC_TOOLBAR_RESET = 0,
|
IC_TOOLBAR_RESET = 0,
|
||||||
IC_TOOLBAR_RESET_HOVER,
|
IC_TOOLBAR_RESET_HOVER,
|
||||||
|
IC_TOOLBAR_RESET_ZERO,
|
||||||
|
IC_TOOLBAR_RESET_ZERO_HOVER,
|
||||||
IC_TOOLBAR_TOOLTIP,
|
IC_TOOLBAR_TOOLTIP,
|
||||||
IC_TOOLBAR_TOOLTIP_HOVER,
|
IC_TOOLBAR_TOOLTIP_HOVER,
|
||||||
IC_NAME_COUNT,
|
IC_NAME_COUNT,
|
||||||
|
@ -261,6 +263,8 @@ public:
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_paint_gizmo();
|
||||||
|
bool is_allow_select_all();
|
||||||
ClippingPlane get_clipping_plane() const;
|
ClippingPlane get_clipping_plane() const;
|
||||||
ClippingPlane get_assemble_view_clipping_plane() const;
|
ClippingPlane get_assemble_view_clipping_plane() const;
|
||||||
bool wants_reslice_supports_on_undo() const;
|
bool wants_reslice_supports_on_undo() const;
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -4,6 +4,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "libslic3r/Point.hpp"
|
#include "libslic3r/Point.hpp"
|
||||||
|
#include "libslic3r/Geometry.hpp"
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
#include "slic3r/GUI/GUI_Geometry.hpp"
|
#include "slic3r/GUI/GUI_Geometry.hpp"
|
||||||
|
@ -30,6 +31,8 @@ public:
|
||||||
Vec3d position_rounded;
|
Vec3d position_rounded;
|
||||||
Vec3d rotation;
|
Vec3d rotation;
|
||||||
Vec3d rotation_rounded;
|
Vec3d rotation_rounded;
|
||||||
|
Vec3d absolute_rotation;
|
||||||
|
Vec3d absolute_rotation_rounded;
|
||||||
Vec3d scale;
|
Vec3d scale;
|
||||||
Vec3d scale_rounded;
|
Vec3d scale_rounded;
|
||||||
Vec3d size;
|
Vec3d size;
|
||||||
|
@ -56,7 +59,7 @@ public:
|
||||||
Cache m_cache;
|
Cache m_cache;
|
||||||
|
|
||||||
bool m_imperial_units { false };
|
bool m_imperial_units { false };
|
||||||
|
bool m_use_object_cs{false};
|
||||||
// Mirroring buttons and their current state
|
// Mirroring buttons and their current state
|
||||||
//enum MirrorButtonState {
|
//enum MirrorButtonState {
|
||||||
// mbHidden,
|
// mbHidden,
|
||||||
|
@ -75,19 +78,28 @@ public:
|
||||||
std::string m_new_unit_string;
|
std::string m_new_unit_string;
|
||||||
Vec3d m_new_position;
|
Vec3d m_new_position;
|
||||||
Vec3d m_new_rotation;
|
Vec3d m_new_rotation;
|
||||||
|
Vec3d m_new_absolute_rotation;
|
||||||
Vec3d m_new_scale;
|
Vec3d m_new_scale;
|
||||||
Vec3d m_new_size;
|
Vec3d m_new_size;
|
||||||
|
Vec3d m_unscale_size;
|
||||||
Vec3d m_buffered_position;
|
Vec3d m_buffered_position;
|
||||||
Vec3d m_buffered_rotation;
|
Vec3d m_buffered_rotation;
|
||||||
|
Vec3d m_buffered_absolute_rotation;
|
||||||
Vec3d m_buffered_scale;
|
Vec3d m_buffered_scale;
|
||||||
Vec3d m_buffered_size;
|
Vec3d m_buffered_size;
|
||||||
|
Vec3d cs_center;
|
||||||
bool m_new_enabled {true};
|
bool m_new_enabled {true};
|
||||||
bool m_uniform_scale {true};
|
bool m_uniform_scale {true};
|
||||||
ECoordinatesType m_coordinates_type{ ECoordinatesType::World };
|
// Does the object manipulation panel work in World or Local coordinates?
|
||||||
|
ECoordinatesType m_coordinates_type{ECoordinatesType::World};
|
||||||
|
|
||||||
|
bool m_show_reset_0_rotation{false};
|
||||||
bool m_show_clear_rotation { false };
|
bool m_show_clear_rotation { false };
|
||||||
bool m_show_clear_scale { false };
|
bool m_show_clear_scale { false };
|
||||||
bool m_show_drop_to_bed { false };
|
bool m_show_drop_to_bed { false };
|
||||||
|
enum class RotateType { None, Relative, Absolute
|
||||||
|
};
|
||||||
|
RotateType m_last_rotate_type{RotateType::None}; // 0:no input 1:relative 2:absolute
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float last_move_input_window_width = 0.0f;
|
float last_move_input_window_width = 0.0f;
|
||||||
|
@ -108,21 +120,33 @@ public:
|
||||||
|
|
||||||
void set_uniform_scaling(const bool uniform_scale);
|
void set_uniform_scaling(const bool uniform_scale);
|
||||||
bool get_uniform_scaling() const { return m_uniform_scale; }
|
bool get_uniform_scaling() const { return m_uniform_scale; }
|
||||||
|
void set_use_object_cs(bool flag){ if (m_use_object_cs != flag) m_use_object_cs = flag; }
|
||||||
|
bool get_use_object_cs() { return m_use_object_cs; }
|
||||||
|
// Does the object manipulation panel work in World or Local coordinates?
|
||||||
|
void set_coordinates_type(ECoordinatesType type);
|
||||||
|
ECoordinatesType get_coordinates_type() const { return m_coordinates_type; }
|
||||||
|
bool is_world_coordinates() const { return m_coordinates_type == ECoordinatesType::World; }
|
||||||
|
bool is_instance_coordinates() const { return m_coordinates_type == ECoordinatesType::Instance; }
|
||||||
|
bool is_local_coordinates() const { return m_coordinates_type == ECoordinatesType::Local; }
|
||||||
|
|
||||||
void set_coordinates_type(ECoordinatesType type);
|
const Cache& get_cache() {return m_cache; }
|
||||||
ECoordinatesType get_coordinates_type() const;
|
|
||||||
bool is_world_coordinates() const { return m_coordinates_type == ECoordinatesType::World; }
|
|
||||||
bool is_instance_coordinates() const { return m_coordinates_type == ECoordinatesType::Instance; }
|
|
||||||
bool is_local_coordinates() const { return m_coordinates_type == ECoordinatesType::Local; }
|
|
||||||
|
|
||||||
void reset_cache() { m_cache.reset(); }
|
void reset_cache() { m_cache.reset(); }
|
||||||
|
|
||||||
|
void limit_scaling_ratio(Vec3d &scaling_factor) const;
|
||||||
void on_change(const std::string& opt_key, int axis, double new_value);
|
void on_change(const std::string& opt_key, int axis, double new_value);
|
||||||
|
bool render_combo(ImGuiWrapper *imgui_wrapper, const std::string &label, const std::vector<std::string> &lines, size_t &selection_idx, float label_width, float item_width);
|
||||||
void do_render_move_window(ImGuiWrapper *imgui_wrapper, std::string window_name, float x, float y, float bottom_limit);
|
void do_render_move_window(ImGuiWrapper *imgui_wrapper, std::string window_name, float x, float y, float bottom_limit);
|
||||||
void do_render_rotate_window(ImGuiWrapper *imgui_wrapper, std::string window_name, float x, float y, float bottom_limit);
|
void do_render_rotate_window(ImGuiWrapper *imgui_wrapper, std::string window_name, float x, float y, float bottom_limit);
|
||||||
void do_render_scale_input_window(ImGuiWrapper* imgui_wrapper, std::string window_name, float x, float y, float bottom_limit);
|
void do_render_scale_input_window(ImGuiWrapper* imgui_wrapper, std::string window_name, float x, float y, float bottom_limit);
|
||||||
float max_unit_size(int number, Vec3d &vec1, Vec3d &vec2,std::string str);
|
float max_unit_size(int number, Vec3d &vec1, Vec3d &vec2,std::string str);
|
||||||
bool reset_button(ImGuiWrapper *imgui_wrapper, float caption_max, float unit_size, float space_size, float end_text_size);
|
bool reset_button(ImGuiWrapper *imgui_wrapper, float caption_max, float unit_size, float space_size, float end_text_size);
|
||||||
|
bool reset_zero_button(ImGuiWrapper *imgui_wrapper, float caption_max, float unit_size, float space_size, float end_text_size);
|
||||||
|
bool bbl_checkbox(const wxString &label, bool &value);
|
||||||
|
|
||||||
|
void show_move_tooltip_information(ImGuiWrapper *imgui_wrapper, float caption_max, float x, float y);
|
||||||
|
void show_rotate_tooltip_information(ImGuiWrapper *imgui_wrapper, float caption_max, float x, float y);
|
||||||
|
void show_scale_tooltip_information(ImGuiWrapper *imgui_wrapper, float caption_max, float x, float y);
|
||||||
|
void set_init_rotation(const Geometry::Transformation &value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void reset_settings_value();
|
void reset_settings_value();
|
||||||
|
@ -134,18 +158,24 @@ private:
|
||||||
//Show or hide mirror buttons
|
//Show or hide mirror buttons
|
||||||
//void update_mirror_buttons_visibility();
|
//void update_mirror_buttons_visibility();
|
||||||
|
|
||||||
// change values
|
// change values
|
||||||
void change_position_value(int axis, double value);
|
void change_position_value(int axis, double value);
|
||||||
void change_rotation_value(int axis, double value);
|
void change_rotation_value(int axis, double value);
|
||||||
|
void change_absolute_rotation_value(int axis, double value);
|
||||||
void change_scale_value(int axis, double value);
|
void change_scale_value(int axis, double value);
|
||||||
void change_size_value(int axis, double value);
|
void change_size_value(int axis, double value);
|
||||||
void do_scale(int axis, const Vec3d &scale) const;
|
void do_scale(int axis, const Vec3d &scale) const;
|
||||||
void reset_position_value();
|
void reset_position_value();
|
||||||
void reset_rotation_value();
|
void reset_rotation_value(bool reset_relative);
|
||||||
void reset_scale_value();
|
void reset_scale_value();
|
||||||
|
|
||||||
GLCanvas3D& m_glcanvas;
|
GLCanvas3D& m_glcanvas;
|
||||||
unsigned int m_last_active_item { 0 };
|
unsigned int m_last_active_item { 0 };
|
||||||
|
std::map<std::string, wxString> m_desc_move;
|
||||||
|
std::map<std::string, wxString> m_desc_rotate;
|
||||||
|
std::map<std::string, wxString> m_desc_scale;
|
||||||
|
Vec3d m_init_rotation;
|
||||||
|
Transform3d m_init_rotation_scale_tran;
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -401,6 +401,39 @@ void Selection::remove_volumes(EMode mode, const std::vector<unsigned int>& volu
|
||||||
this->set_bounding_boxes_dirty();
|
this->set_bounding_boxes_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ModelVolume *Selection::get_selected_single_volume(int &out_object_idx, int &out_volume_idx) const
|
||||||
|
{
|
||||||
|
if (is_single_volume() || is_single_modifier()) {
|
||||||
|
const GLVolume *gl_volume = get_first_volume();
|
||||||
|
out_object_idx = gl_volume->object_idx();
|
||||||
|
ModelObject *model_object = get_model()->objects[out_object_idx];
|
||||||
|
out_volume_idx = gl_volume->volume_idx();
|
||||||
|
if (out_volume_idx < model_object->volumes.size())
|
||||||
|
return model_object->volumes[out_volume_idx];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelObject *Selection::get_selected_single_object(int &out_object_idx) const
|
||||||
|
{
|
||||||
|
if (is_single_volume() || is_single_modifier() || is_single_full_object()) {
|
||||||
|
const GLVolume *gl_volume = get_first_volume();
|
||||||
|
out_object_idx = gl_volume->object_idx();
|
||||||
|
return get_model()->objects[out_object_idx];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModelInstance *Selection::get_selected_single_intance() const
|
||||||
|
{
|
||||||
|
int object_idx;
|
||||||
|
auto mo = get_selected_single_object(object_idx);
|
||||||
|
if (mo) {
|
||||||
|
return mo->instances[get_instance_idx()];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void Selection::add_curr_plate()
|
void Selection::add_curr_plate()
|
||||||
{
|
{
|
||||||
if (!m_valid)
|
if (!m_valid)
|
||||||
|
@ -910,17 +943,17 @@ const BoundingBoxf3& Selection::get_scaled_instance_bounding_box() const
|
||||||
return *m_scaled_instance_bounding_box;
|
return *m_scaled_instance_bounding_box;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BoundingBoxf3& Selection::get_full_unscaled_instance_bounding_box() const
|
const BoundingBoxf3 &Selection::get_full_unscaled_instance_bounding_box() const
|
||||||
{
|
{
|
||||||
assert(is_single_full_instance());
|
assert(is_single_full_instance());
|
||||||
|
|
||||||
if (!m_full_unscaled_instance_bounding_box.has_value()) {
|
if (!m_full_unscaled_instance_bounding_box.has_value()) {
|
||||||
std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_full_unscaled_instance_bounding_box);
|
std::optional<BoundingBoxf3> *bbox = const_cast<std::optional<BoundingBoxf3> *>(&m_full_unscaled_instance_bounding_box);
|
||||||
*bbox = BoundingBoxf3();
|
*bbox = BoundingBoxf3();
|
||||||
if (m_valid) {
|
if (m_valid) {
|
||||||
for (unsigned int i : m_list) {
|
for (unsigned int i : m_list) {
|
||||||
const GLVolume& volume = *(*m_volumes)[i];
|
const GLVolume &volume = *(*m_volumes)[i];
|
||||||
Transform3d trafo = volume.get_instance_transformation().get_matrix_no_scaling_factor() * volume.get_volume_transformation().get_matrix();
|
Transform3d trafo = volume.get_instance_transformation().get_matrix_no_scaling_factor() * volume.get_volume_transformation().get_matrix();
|
||||||
trafo.translation().z() += volume.get_sla_shift_z();
|
trafo.translation().z() += volume.get_sla_shift_z();
|
||||||
(*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
|
(*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
|
||||||
}
|
}
|
||||||
|
@ -929,17 +962,17 @@ const BoundingBoxf3& Selection::get_full_unscaled_instance_bounding_box() const
|
||||||
return *m_full_unscaled_instance_bounding_box;
|
return *m_full_unscaled_instance_bounding_box;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BoundingBoxf3& Selection::get_full_scaled_instance_bounding_box() const
|
const BoundingBoxf3 &Selection::get_full_scaled_instance_bounding_box() const
|
||||||
{
|
{
|
||||||
assert(is_single_full_instance());
|
assert(is_single_full_instance());
|
||||||
|
|
||||||
if (!m_full_scaled_instance_bounding_box.has_value()) {
|
if (!m_full_scaled_instance_bounding_box.has_value()) {
|
||||||
std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_full_scaled_instance_bounding_box);
|
std::optional<BoundingBoxf3> *bbox = const_cast<std::optional<BoundingBoxf3> *>(&m_full_scaled_instance_bounding_box);
|
||||||
*bbox = BoundingBoxf3();
|
*bbox = BoundingBoxf3();
|
||||||
if (m_valid) {
|
if (m_valid) {
|
||||||
for (unsigned int i : m_list) {
|
for (unsigned int i : m_list) {
|
||||||
const GLVolume& volume = *(*m_volumes)[i];
|
const GLVolume &volume = *(*m_volumes)[i];
|
||||||
Transform3d trafo = volume.get_instance_transformation().get_matrix() * volume.get_volume_transformation().get_matrix();
|
Transform3d trafo = volume.get_instance_transformation().get_matrix() * volume.get_volume_transformation().get_matrix();
|
||||||
trafo.translation().z() += volume.get_sla_shift_z();
|
trafo.translation().z() += volume.get_sla_shift_z();
|
||||||
(*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
|
(*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
|
||||||
}
|
}
|
||||||
|
@ -948,17 +981,17 @@ const BoundingBoxf3& Selection::get_full_scaled_instance_bounding_box() const
|
||||||
return *m_full_scaled_instance_bounding_box;
|
return *m_full_scaled_instance_bounding_box;
|
||||||
}
|
}
|
||||||
|
|
||||||
const BoundingBoxf3& Selection::get_full_unscaled_instance_local_bounding_box() const
|
const BoundingBoxf3 &Selection::get_full_unscaled_instance_local_bounding_box() const
|
||||||
{
|
{
|
||||||
assert(is_single_full_instance());
|
assert(is_single_full_instance());
|
||||||
|
|
||||||
if (!m_full_unscaled_instance_local_bounding_box.has_value()) {
|
if (!m_full_unscaled_instance_local_bounding_box.has_value()) {
|
||||||
std::optional<BoundingBoxf3>* bbox = const_cast<std::optional<BoundingBoxf3>*>(&m_full_unscaled_instance_local_bounding_box);
|
std::optional<BoundingBoxf3> *bbox = const_cast<std::optional<BoundingBoxf3> *>(&m_full_unscaled_instance_local_bounding_box);
|
||||||
*bbox = BoundingBoxf3();
|
*bbox = BoundingBoxf3();
|
||||||
if (m_valid) {
|
if (m_valid) {
|
||||||
for (unsigned int i : m_list) {
|
for (unsigned int i : m_list) {
|
||||||
const GLVolume& volume = *(*m_volumes)[i];
|
const GLVolume &volume = *(*m_volumes)[i];
|
||||||
Transform3d trafo = volume.get_volume_transformation().get_matrix();
|
Transform3d trafo = volume.get_volume_transformation().get_matrix();
|
||||||
trafo.translation().z() += volume.get_sla_shift_z();
|
trafo.translation().z() += volume.get_sla_shift_z();
|
||||||
(*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
|
(*bbox)->merge(volume.transformed_convex_hull_bounding_box(trafo));
|
||||||
}
|
}
|
||||||
|
@ -967,22 +1000,20 @@ const BoundingBoxf3& Selection::get_full_unscaled_instance_local_bounding_box()
|
||||||
return *m_full_unscaled_instance_local_bounding_box;
|
return *m_full_unscaled_instance_local_bounding_box;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::pair<BoundingBoxf3, Transform3d>& Selection::get_bounding_box_in_current_reference_system() const
|
const std::pair<BoundingBoxf3, Transform3d> &Selection::get_bounding_box_in_current_reference_system() const
|
||||||
{
|
{
|
||||||
static int last_coordinates_type = -1;
|
static int last_coordinates_type = -1;
|
||||||
|
|
||||||
assert(!is_empty());
|
assert(!is_empty());
|
||||||
|
|
||||||
ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
ECoordinatesType coordinates_type = wxGetApp().obj_manipul()->get_coordinates_type();
|
||||||
if (m_mode == Instance && coordinates_type == ECoordinatesType::Local)
|
if (m_mode == Instance && coordinates_type == ECoordinatesType::Local) coordinates_type = ECoordinatesType::World;
|
||||||
coordinates_type = ECoordinatesType::World;
|
|
||||||
|
|
||||||
if (last_coordinates_type != int(coordinates_type))
|
if (last_coordinates_type != int(coordinates_type)) const_cast<std::optional<std::pair<BoundingBoxf3, Transform3d>> *>(&m_bounding_box_in_current_reference_system)->reset();
|
||||||
const_cast<std::optional<std::pair<BoundingBoxf3, Transform3d>>*>(&m_bounding_box_in_current_reference_system)->reset();
|
|
||||||
|
|
||||||
if (!m_bounding_box_in_current_reference_system.has_value()) {
|
if (!m_bounding_box_in_current_reference_system.has_value()) {
|
||||||
last_coordinates_type = int(coordinates_type);
|
last_coordinates_type = int(coordinates_type);
|
||||||
*const_cast<std::optional<std::pair<BoundingBoxf3, Transform3d>>*>(&m_bounding_box_in_current_reference_system) = get_bounding_box_in_reference_system(coordinates_type);
|
*const_cast<std::optional<std::pair<BoundingBoxf3, Transform3d>> *>(&m_bounding_box_in_current_reference_system) = get_bounding_box_in_reference_system(coordinates_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
return *m_bounding_box_in_current_reference_system;
|
return *m_bounding_box_in_current_reference_system;
|
||||||
|
@ -994,11 +1025,19 @@ std::pair<BoundingBoxf3, Transform3d> Selection::get_bounding_box_in_reference_s
|
||||||
// trafo to current reference system
|
// trafo to current reference system
|
||||||
//
|
//
|
||||||
Transform3d trafo;
|
Transform3d trafo;
|
||||||
switch (type)
|
switch (type) {
|
||||||
{
|
case ECoordinatesType::World: {
|
||||||
case ECoordinatesType::World: { trafo = Transform3d::Identity(); break; }
|
trafo = Transform3d::Identity();
|
||||||
case ECoordinatesType::Instance: { trafo = get_first_volume()->get_instance_transformation().get_matrix(); break; }
|
break;
|
||||||
case ECoordinatesType::Local: { trafo = get_first_volume()->world_matrix(); break; }
|
}
|
||||||
|
case ECoordinatesType::Instance: {
|
||||||
|
trafo = get_first_volume()->get_instance_transformation().get_matrix();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ECoordinatesType::Local: {
|
||||||
|
trafo = get_first_volume()->world_matrix();
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -1006,60 +1045,55 @@ std::pair<BoundingBoxf3, Transform3d> Selection::get_bounding_box_in_reference_s
|
||||||
//
|
//
|
||||||
Geometry::Transformation t(trafo);
|
Geometry::Transformation t(trafo);
|
||||||
t.reset_scaling_factor();
|
t.reset_scaling_factor();
|
||||||
const Transform3d basis_trafo = t.get_matrix_no_offset();
|
const Transform3d basis_trafo = t.get_matrix_no_offset();
|
||||||
std::vector<Vec3d> axes = { Vec3d::UnitX(), Vec3d::UnitY(), Vec3d::UnitZ() };
|
std::vector<Vec3d> axes = {Vec3d::UnitX(), Vec3d::UnitY(), Vec3d::UnitZ()};
|
||||||
for (size_t i = 0; i < axes.size(); ++i) {
|
for (size_t i = 0; i < axes.size(); ++i) { axes[i] = basis_trafo * axes[i]; }
|
||||||
axes[i] = basis_trafo * axes[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// calculate bounding box aligned to trafo basis
|
// calculate bounding box aligned to trafo basis
|
||||||
//
|
//
|
||||||
Vec3d min = { DBL_MAX, DBL_MAX, DBL_MAX };
|
Vec3d min = {DBL_MAX, DBL_MAX, DBL_MAX};
|
||||||
Vec3d max = { -DBL_MAX, -DBL_MAX, -DBL_MAX };
|
Vec3d max = {-DBL_MAX, -DBL_MAX, -DBL_MAX};
|
||||||
for (unsigned int id : m_list) {
|
for (unsigned int id : m_list) {
|
||||||
const GLVolume& vol = *get_volume(id);
|
const GLVolume & vol = *get_volume(id);
|
||||||
const Transform3d vol_world_rafo = vol.world_matrix();
|
const Transform3d vol_world_rafo = vol.world_matrix();
|
||||||
const TriangleMesh* mesh = vol.convex_hull();
|
const TriangleMesh *mesh = vol.convex_hull();
|
||||||
if (mesh == nullptr)
|
if (mesh == nullptr)
|
||||||
mesh = &m_model->objects[vol.object_idx()]->volumes[vol.volume_idx()]->mesh();
|
mesh = &m_model->objects[vol.object_idx()]->volumes[vol.volume_idx()]->mesh();
|
||||||
assert(mesh != nullptr);
|
assert(mesh != nullptr);
|
||||||
for (const stl_vertex& v : mesh->its.vertices) {
|
for (const stl_vertex &v : mesh->its.vertices) {
|
||||||
const Vec3d world_v = vol_world_rafo * v.cast<double>();
|
const Vec3d world_v = vol_world_rafo * v.cast<double>();
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
const double i_comp = world_v.dot(axes[i]);
|
const double i_comp = world_v.dot(axes[i]);
|
||||||
min(i) = std::min(min(i), i_comp);
|
min(i) = std::min(min(i), i_comp);
|
||||||
max(i) = std::max(max(i), i_comp);
|
max(i) = std::max(max(i), i_comp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Vec3d box_size = max - min;
|
const Vec3d box_size = max - min;
|
||||||
Vec3d half_box_size = 0.5 * box_size;
|
Vec3d half_box_size = 0.5 * box_size;
|
||||||
Geometry::Transformation out_trafo(trafo);
|
Geometry::Transformation out_trafo(trafo);
|
||||||
Vec3d center = 0.5 * (min + max);
|
Vec3d center = 0.5 * (min + max);
|
||||||
|
|
||||||
// Fix for non centered volume
|
// Fix for non centered volume
|
||||||
// by move with calculated center(to volume center) and extend half box size
|
// by move with calculated center(to volume center) and extend half box size
|
||||||
// e.g. for right aligned embossed text
|
// e.g. for right aligned embossed text
|
||||||
if (m_list.size() == 1 &&
|
if (m_list.size() == 1 && type == ECoordinatesType::Local) {
|
||||||
type == ECoordinatesType::Local) {
|
const GLVolume & vol = *get_volume(*m_list.begin());
|
||||||
const GLVolume& vol = *get_volume(*m_list.begin());
|
|
||||||
const Transform3d vol_world_trafo = vol.world_matrix();
|
const Transform3d vol_world_trafo = vol.world_matrix();
|
||||||
Vec3d world_zero = vol_world_trafo * Vec3d::Zero();
|
Vec3d world_zero = vol_world_trafo * Vec3d::Zero();
|
||||||
for (size_t i = 0; i < 3; i++){
|
for (size_t i = 0; i < 3; i++) {
|
||||||
// move center to local volume zero
|
// move center to local volume zero
|
||||||
center[i] = world_zero.dot(axes[i]);
|
center[i] = world_zero.dot(axes[i]);
|
||||||
// extend half size to bigger distance from center
|
// extend half size to bigger distance from center
|
||||||
half_box_size[i] = std::max(
|
half_box_size[i] = std::max(abs(center[i] - min[i]), abs(center[i] - max[i]));
|
||||||
abs(center[i] - min[i]),
|
|
||||||
abs(center[i] - max[i]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const BoundingBoxf3 out_box(-half_box_size, half_box_size);
|
const BoundingBoxf3 out_box(-half_box_size, half_box_size);
|
||||||
out_trafo.set_offset(basis_trafo * center);
|
out_trafo.set_offset(basis_trafo * center);
|
||||||
return { out_box, out_trafo.get_matrix_no_scaling_factor() };
|
return {out_box, out_trafo.get_matrix_no_scaling_factor()};
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::pair<Vec3d, double> Selection::get_bounding_sphere() const
|
const std::pair<Vec3d, double> Selection::get_bounding_sphere() const
|
||||||
|
@ -1138,34 +1172,52 @@ void Selection::move_to_center(const Vec3d& displacement, bool local)
|
||||||
this->set_bounding_boxes_dirty();
|
this->set_bounding_boxes_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selection::translate(const Vec3d& displacement, TransformationType transformation_type)
|
void Selection::translate(const Vec3d &displacement, TransformationType transformation_type)
|
||||||
{
|
{
|
||||||
if (!m_valid)
|
if (!m_valid) return;
|
||||||
return;
|
|
||||||
|
|
||||||
// Emboss use translate in local coordinate
|
|
||||||
assert(transformation_type.relative() ||
|
|
||||||
transformation_type.local());
|
|
||||||
|
|
||||||
for (unsigned int i : m_list) {
|
for (unsigned int i : m_list) {
|
||||||
GLVolume& v = *(*m_volumes)[i];
|
GLVolume & v = *(*m_volumes)[i];
|
||||||
const VolumeCache& volume_data = m_cache.volumes_data[i];
|
const VolumeCache &volume_data = m_cache.volumes_data[i];
|
||||||
if (m_mode == Instance && !is_wipe_tower()) {
|
if (m_mode == Instance && !is_wipe_tower()) {
|
||||||
assert(is_from_fully_selected_instance(i));
|
assert(is_from_fully_selected_instance(i));
|
||||||
if (transformation_type.instance()) {
|
if (transformation_type.instance()) {
|
||||||
const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
|
const Geometry::Transformation &inst_trafo = volume_data.get_instance_transform();
|
||||||
v.set_instance_offset(inst_trafo.get_offset() + inst_trafo.get_rotation_matrix() * displacement);
|
v.set_instance_offset(inst_trafo.get_offset() + inst_trafo.get_rotation_matrix() * displacement);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center);
|
transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(displacement), m_cache.dragging_center);
|
||||||
}
|
} else {
|
||||||
else {
|
if (v.is_wipe_tower) {//in world cs
|
||||||
if (transformation_type.local() && transformation_type.absolute()) {
|
int plate_idx = v.object_idx() - 1000;
|
||||||
const Geometry::Transformation& vol_trafo = volume_data.get_volume_transform();
|
BoundingBoxf3 plate_bbox = wxGetApp().plater()->get_partplate_list().get_plate(plate_idx)->get_bounding_box();
|
||||||
const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
|
Vec3d tower_size = v.bounding_box().size();
|
||||||
v.set_volume_offset(vol_trafo.get_offset() + inst_trafo.get_scaling_factor_matrix().inverse() * vol_trafo.get_rotation_matrix() * displacement);
|
Vec3d tower_origin = m_cache.volumes_data[i].get_volume_position();
|
||||||
|
Vec3d actual_displacement = displacement;
|
||||||
|
const double margin = WIPE_TOWER_MARGIN;
|
||||||
|
|
||||||
|
actual_displacement = (m_cache.volumes_data[i].get_instance_rotation_matrix() * m_cache.volumes_data[i].get_instance_scale_matrix() *
|
||||||
|
m_cache.volumes_data[i].get_instance_mirror_matrix())
|
||||||
|
.inverse() *
|
||||||
|
displacement;
|
||||||
|
if (tower_origin(0) + actual_displacement(0) - margin < plate_bbox.min(0)) {
|
||||||
|
actual_displacement(0) = plate_bbox.min(0) - tower_origin(0) + margin;
|
||||||
|
} else if (tower_origin(0) + actual_displacement(0) + tower_size(0) + margin > plate_bbox.max(0)) {
|
||||||
|
actual_displacement(0) = plate_bbox.max(0) - tower_origin(0) - tower_size(0) - margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tower_origin(1) + actual_displacement(1) - margin < plate_bbox.min(1)) {
|
||||||
|
actual_displacement(1) = plate_bbox.min(1) - tower_origin(1) + margin;
|
||||||
|
} else if (tower_origin(1) + actual_displacement(1) + tower_size(1) + margin > plate_bbox.max(1)) {
|
||||||
|
actual_displacement(1) = plate_bbox.max(1) - tower_origin(1) - tower_size(1) - margin;
|
||||||
|
}
|
||||||
|
|
||||||
|
v.set_volume_offset(m_cache.volumes_data[i].get_volume_position() + actual_displacement);
|
||||||
}
|
}
|
||||||
else {
|
else if (transformation_type.local() && transformation_type.absolute()) {
|
||||||
|
const Geometry::Transformation &vol_trafo = volume_data.get_volume_transform();
|
||||||
|
const Geometry::Transformation &inst_trafo = volume_data.get_instance_transform();
|
||||||
|
v.set_volume_offset(vol_trafo.get_offset() + inst_trafo.get_scaling_factor_matrix().inverse() * vol_trafo.get_rotation_matrix() * displacement);
|
||||||
|
} else {
|
||||||
Vec3d relative_disp = displacement;
|
Vec3d relative_disp = displacement;
|
||||||
if (transformation_type.world() && transformation_type.instance())
|
if (transformation_type.world() && transformation_type.instance())
|
||||||
relative_disp = volume_data.get_instance_transform().get_scaling_factor_matrix().inverse() * relative_disp;
|
relative_disp = volume_data.get_instance_transform().get_scaling_factor_matrix().inverse() * relative_disp;
|
||||||
|
@ -1181,12 +1233,14 @@ void Selection::translate(const Vec3d& displacement, TransformationType transfor
|
||||||
else if (m_mode == Volume)
|
else if (m_mode == Volume)
|
||||||
synchronize_unselected_volumes();
|
synchronize_unselected_volumes();
|
||||||
#endif // !DISABLE_INSTANCES_SYNCH
|
#endif // !DISABLE_INSTANCES_SYNCH
|
||||||
|
if (wxGetApp().plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasAssembleView) {
|
||||||
ensure_not_below_bed();
|
ensure_not_below_bed();
|
||||||
|
}
|
||||||
set_bounding_boxes_dirty();
|
set_bounding_boxes_dirty();
|
||||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
if (wxGetApp().plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasAssembleView) {
|
||||||
|
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotate an object around one of the axes. Only one rotation component is expected to be changing.
|
// Rotate an object around one of the axes. Only one rotation component is expected to be changing.
|
||||||
void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type)
|
void Selection::rotate(const Vec3d& rotation, TransformationType transformation_type)
|
||||||
{
|
{
|
||||||
|
@ -1287,7 +1341,9 @@ void Selection::rotate(const Vec3d& rotation, TransformationType transformation_
|
||||||
#endif // !DISABLE_INSTANCES_SYNCH
|
#endif // !DISABLE_INSTANCES_SYNCH
|
||||||
|
|
||||||
set_bounding_boxes_dirty();
|
set_bounding_boxes_dirty();
|
||||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
if (wxGetApp().plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasAssembleView) {
|
||||||
|
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selection::flattening_rotate(const Vec3d& normal)
|
void Selection::flattening_rotate(const Vec3d& normal)
|
||||||
|
@ -1320,96 +1376,6 @@ void Selection::flattening_rotate(const Vec3d& normal)
|
||||||
this->set_bounding_boxes_dirty();
|
this->set_bounding_boxes_dirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selection::scale_legacy(const Vec3d& scale, TransformationType transformation_type)
|
|
||||||
{
|
|
||||||
if (!m_valid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (unsigned int i : m_list) {
|
|
||||||
GLVolume &v = *(*m_volumes)[i];
|
|
||||||
if (is_single_full_instance()) {
|
|
||||||
if (transformation_type.relative()) {
|
|
||||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
|
|
||||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3);
|
|
||||||
// extracts scaling factors from the composed transformation
|
|
||||||
Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
|
||||||
if (transformation_type.joint())
|
|
||||||
v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
|
||||||
|
|
||||||
v.set_instance_scaling_factor(new_scale);
|
|
||||||
// Restore mirror state
|
|
||||||
v.set_instance_mirror(m_cache.volumes_data[i].get_instance_transform().get_mirror());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
const auto mirror = v.get_instance_mirror();
|
|
||||||
if (transformation_type.world() && (std::abs(scale.x() - scale.y()) > EPSILON || std::abs(scale.x() - scale.z()) > EPSILON)) {
|
|
||||||
// Non-uniform scaling. Transform the scaling factors into the local coordinate system.
|
|
||||||
// This is only possible, if the instance rotation is mulitples of ninety degrees.
|
|
||||||
assert(Geometry::is_rotation_ninety_degrees(v.get_instance_rotation()));
|
|
||||||
v.set_instance_scaling_factor((v.get_instance_transformation().get_rotation_matrix().matrix().block<3, 3>(0, 0).transpose() * scale).cwiseAbs());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
v.set_instance_scaling_factor(scale);
|
|
||||||
// Restore mirror state
|
|
||||||
v.set_instance_mirror(mirror);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the instance assemble transform
|
|
||||||
ModelObject* object = m_model->objects[v.object_idx()];
|
|
||||||
Geometry::Transformation assemble_transform = object->instances[v.instance_idx()]->get_assemble_transformation();
|
|
||||||
const auto mirror = assemble_transform.get_mirror();
|
|
||||||
assemble_transform.set_scaling_factor(v.get_instance_scaling_factor());
|
|
||||||
assemble_transform.set_mirror(mirror);
|
|
||||||
object->instances[v.instance_idx()]->set_assemble_transformation(assemble_transform);
|
|
||||||
}
|
|
||||||
else if (is_single_volume() || is_single_modifier()) {
|
|
||||||
const auto mirror = v.get_volume_transformation().get_mirror();
|
|
||||||
v.set_volume_scaling_factor(scale);
|
|
||||||
// Restore mirror state
|
|
||||||
v.set_volume_mirror(mirror);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Transform3d m = Geometry::assemble_transform(Vec3d::Zero(), Vec3d::Zero(), scale);
|
|
||||||
if (m_mode == Instance) {
|
|
||||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_instance_scale_matrix()).matrix().block(0, 0, 3, 3);
|
|
||||||
// extracts scaling factors from the composed transformation
|
|
||||||
Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
|
||||||
if (transformation_type.joint())
|
|
||||||
v.set_instance_offset(m_cache.dragging_center + m * (m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center));
|
|
||||||
|
|
||||||
v.set_instance_scaling_factor(new_scale);
|
|
||||||
// Restore mirror state
|
|
||||||
v.set_instance_mirror(m_cache.volumes_data[i].get_instance_transform().get_mirror());
|
|
||||||
}
|
|
||||||
else if (m_mode == Volume) {
|
|
||||||
Eigen::Matrix<double, 3, 3, Eigen::DontAlign> new_matrix = (m * m_cache.volumes_data[i].get_volume_scale_matrix()).matrix().block(0, 0, 3, 3);
|
|
||||||
// extracts scaling factors from the composed transformation
|
|
||||||
Vec3d new_scale(new_matrix.col(0).norm(), new_matrix.col(1).norm(), new_matrix.col(2).norm());
|
|
||||||
if (transformation_type.joint()) {
|
|
||||||
Vec3d offset = m * (m_cache.volumes_data[i].get_volume_position() + m_cache.volumes_data[i].get_instance_position() - m_cache.dragging_center);
|
|
||||||
v.set_volume_offset(m_cache.dragging_center - m_cache.volumes_data[i].get_instance_position() + offset);
|
|
||||||
}
|
|
||||||
v.set_volume_scaling_factor(new_scale);
|
|
||||||
// Restore mirror state
|
|
||||||
v.set_volume_mirror(m_cache.volumes_data[i].get_volume_transform().get_mirror());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !DISABLE_INSTANCES_SYNCH
|
|
||||||
if (m_mode == Instance)
|
|
||||||
// even if there is no rotation, we pass SyncRotationType::GENERAL to force
|
|
||||||
// synchronize_unselected_instances() to apply the scale to the other instances
|
|
||||||
synchronize_unselected_instances(SyncRotationType::GENERAL);
|
|
||||||
else if (m_mode == Volume)
|
|
||||||
synchronize_unselected_volumes();
|
|
||||||
#endif // !DISABLE_INSTANCES_SYNCH
|
|
||||||
|
|
||||||
ensure_on_bed();
|
|
||||||
set_bounding_boxes_dirty();
|
|
||||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Selection::scale(const Vec3d& scale, TransformationType transformation_type)
|
void Selection::scale(const Vec3d& scale, TransformationType transformation_type)
|
||||||
{
|
{
|
||||||
scale_and_translate(scale, Vec3d::Zero(), transformation_type);
|
scale_and_translate(scale, Vec3d::Zero(), transformation_type);
|
||||||
|
@ -1552,16 +1518,9 @@ void Selection::scale_to_fit_print_volume(const DynamicPrintConfig& config)
|
||||||
}
|
}
|
||||||
#endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
#endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
||||||
|
|
||||||
void Selection::mirror(Axis axis, TransformationType transformation_type)
|
void Selection::scale_and_translate(const Vec3d &scale, const Vec3d &world_translation, TransformationType transformation_type)
|
||||||
{
|
{
|
||||||
const Vec3d mirror((axis == X) ? -1.0 : 1.0, (axis == Y) ? -1.0 : 1.0, (axis == Z) ? -1.0 : 1.0);
|
if (!m_valid) return;
|
||||||
scale_and_translate(mirror, Vec3d::Zero(), transformation_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& world_translation, TransformationType transformation_type)
|
|
||||||
{
|
|
||||||
if (!m_valid)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Vec3d relative_scale = scale;
|
Vec3d relative_scale = scale;
|
||||||
if (transformation_type.absolute()) {
|
if (transformation_type.absolute()) {
|
||||||
|
@ -1582,45 +1541,52 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& world_trans
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i : m_list) {
|
for (unsigned int i : m_list) {
|
||||||
GLVolume& v = *(*m_volumes)[i];
|
GLVolume & v = *(*m_volumes)[i];
|
||||||
const VolumeCache& volume_data = m_cache.volumes_data[i];
|
const VolumeCache & volume_data = m_cache.volumes_data[i];
|
||||||
const Geometry::Transformation& inst_trafo = volume_data.get_instance_transform();
|
const Geometry::Transformation &inst_trafo = volume_data.get_instance_transform();
|
||||||
|
|
||||||
if (m_mode == Instance) {
|
if (m_mode == Instance) {
|
||||||
if (transformation_type.instance()) {
|
if (transformation_type.instance()) {
|
||||||
const Vec3d world_inst_pivot = m_cache.dragging_center - inst_trafo.get_offset();
|
const Vec3d world_inst_pivot = m_cache.dragging_center - inst_trafo.get_offset();
|
||||||
const Vec3d local_inst_pivot = inst_trafo.get_matrix_no_offset().inverse() * world_inst_pivot;
|
const Vec3d local_inst_pivot = inst_trafo.get_matrix_no_offset().inverse() * world_inst_pivot;
|
||||||
Matrix3d inst_rotation, inst_scale;
|
Matrix3d inst_rotation, inst_scale;
|
||||||
inst_trafo.get_matrix().computeRotationScaling(&inst_rotation, &inst_scale);
|
inst_trafo.get_matrix().computeRotationScaling(&inst_rotation, &inst_scale);
|
||||||
const Transform3d offset_trafo = Geometry::translation_transform(inst_trafo.get_offset() + world_translation);
|
const Transform3d offset_trafo = Geometry::translation_transform(inst_trafo.get_offset() + world_translation);
|
||||||
const Transform3d scale_trafo = Transform3d(inst_scale) * Geometry::scale_transform(relative_scale);
|
const Transform3d scale_trafo = Transform3d(inst_scale) * Geometry::scale_transform(relative_scale);
|
||||||
v.set_instance_transformation(Geometry::translation_transform(world_inst_pivot) * offset_trafo * Transform3d(inst_rotation) * scale_trafo * Geometry::translation_transform(-local_inst_pivot));
|
v.set_instance_transformation(Geometry::translation_transform(world_inst_pivot) * offset_trafo * Transform3d(inst_rotation) * scale_trafo *
|
||||||
}
|
Geometry::translation_transform(-local_inst_pivot));
|
||||||
else
|
} else
|
||||||
transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(world_translation) * Geometry::scale_transform(relative_scale), m_cache.dragging_center);
|
transform_instance_relative(v, volume_data, transformation_type, Geometry::translation_transform(world_translation) * Geometry::scale_transform(relative_scale),
|
||||||
}
|
m_cache.dragging_center);
|
||||||
else {
|
// update the instance assemble transform
|
||||||
|
ModelObject * object = m_model->objects[v.object_idx()];
|
||||||
|
Geometry::Transformation assemble_transform = object->instances[v.instance_idx()]->get_assemble_transformation();
|
||||||
|
assemble_transform.set_scaling_factor(v.get_instance_scaling_factor());
|
||||||
|
object->instances[v.instance_idx()]->set_assemble_transformation(assemble_transform);
|
||||||
|
} else {
|
||||||
if (!is_single_volume_or_modifier()) {
|
if (!is_single_volume_or_modifier()) {
|
||||||
assert(transformation_type.world());
|
assert(transformation_type.world());
|
||||||
transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(world_translation) * Geometry::scale_transform(scale), m_cache.dragging_center);
|
transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(world_translation) * Geometry::scale_transform(scale),
|
||||||
}
|
m_cache.dragging_center);
|
||||||
else {
|
} else {
|
||||||
transformation_type.set_independent();
|
transformation_type.set_independent();
|
||||||
Vec3d translation;
|
Vec3d translation;
|
||||||
if (transformation_type.local())
|
if (transformation_type.local()) {
|
||||||
translation = volume_data.get_volume_transform().get_matrix_no_offset().inverse() * inst_trafo.get_matrix_no_offset().inverse() * world_translation;
|
translation = volume_data.get_volume_transform().get_matrix_no_offset().inverse() * inst_trafo.get_matrix_no_offset().inverse() * world_translation;
|
||||||
|
}
|
||||||
else if (transformation_type.instance())
|
else if (transformation_type.instance())
|
||||||
translation = inst_trafo.get_matrix_no_offset().inverse() * world_translation;
|
translation = inst_trafo.get_matrix_no_offset().inverse() * world_translation;
|
||||||
else
|
else
|
||||||
translation = world_translation;
|
translation = world_translation;
|
||||||
transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale), m_cache.dragging_center);
|
transform_volume_relative(v, volume_data, transformation_type, Geometry::translation_transform(translation) * Geometry::scale_transform(scale),
|
||||||
|
m_cache.dragging_center);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !DISABLE_INSTANCES_SYNCH
|
#if !DISABLE_INSTANCES_SYNCH
|
||||||
if (m_mode == Instance)
|
if (m_mode == Instance)
|
||||||
// even if there is no rotation, we pass SyncRotationType::GENERAL to force
|
// even if there is no rotation, we pass SyncRotationType::GENERAL to force
|
||||||
// synchronize_unselected_instances() to apply the scale to the other instances
|
// synchronize_unselected_instances() to apply the scale to the other instances
|
||||||
synchronize_unselected_instances(SyncRotationType::GENERAL);
|
synchronize_unselected_instances(SyncRotationType::GENERAL);
|
||||||
else if (m_mode == Volume)
|
else if (m_mode == Volume)
|
||||||
|
@ -1629,7 +1595,16 @@ void Selection::scale_and_translate(const Vec3d& scale, const Vec3d& world_trans
|
||||||
|
|
||||||
ensure_on_bed();
|
ensure_on_bed();
|
||||||
set_bounding_boxes_dirty();
|
set_bounding_boxes_dirty();
|
||||||
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
if (wxGetApp().plater()->canvas3D()->get_canvas_type() != GLCanvas3D::ECanvasType::CanvasAssembleView) {
|
||||||
|
wxGetApp().plater()->canvas3D()->requires_check_outside_state();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Selection::mirror(Axis axis, TransformationType transformation_type)
|
||||||
|
{
|
||||||
|
const Vec3d mirror((axis == X) ? -1.0 : 1.0, (axis == Y) ? -1.0 : 1.0, (axis == Z) ? -1.0 : 1.0);
|
||||||
|
scale_and_translate(mirror, Vec3d::Zero(), transformation_type);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selection::translate(unsigned int object_idx, const Vec3d& displacement)
|
void Selection::translate(unsigned int object_idx, const Vec3d& displacement)
|
||||||
|
@ -1944,7 +1919,8 @@ void Selection::render(float scale_factor)
|
||||||
m_scale_factor = scale_factor;
|
m_scale_factor = scale_factor;
|
||||||
// render cumulative bounding box of selected volumes
|
// render cumulative bounding box of selected volumes
|
||||||
const auto& [box, trafo] = get_bounding_box_in_current_reference_system();
|
const auto& [box, trafo] = get_bounding_box_in_current_reference_system();
|
||||||
render_bounding_box(box, trafo, ColorRGB::WHITE());
|
render_bounding_box(box, trafo,
|
||||||
|
wxGetApp().plater()->canvas3D()->get_canvas_type() == GLCanvas3D::ECanvasType::CanvasAssembleView ? ColorRGB::YELLOW(): ColorRGB::WHITE());
|
||||||
render_synchronized_volumes();
|
render_synchronized_volumes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1992,40 +1968,33 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, bool unif
|
||||||
|
|
||||||
glsafe(::glEnable(GL_DEPTH_TEST));
|
glsafe(::glEnable(GL_DEPTH_TEST));
|
||||||
|
|
||||||
const Transform3d base_matrix = Geometry::assemble_transform(get_bounding_box().center());
|
Vec3d center = get_bounding_box().center();
|
||||||
Transform3d orient_matrix = Transform3d::Identity();
|
Transform3d orient_matrix = Transform3d::Identity();
|
||||||
|
|
||||||
if (!boost::starts_with(sidebar_field, "layer")) {
|
if (!boost::starts_with(sidebar_field, "layer")) {
|
||||||
shader->set_uniform("emission_factor", 0.05f);
|
shader->set_uniform("emission_factor", 0.05f);
|
||||||
|
const auto &[box, box_trafo] = get_bounding_box_in_current_reference_system();
|
||||||
// BBS
|
// BBS
|
||||||
if (is_single_full_instance()/* && !wxGetApp().obj_manipul()->get_world_coordinates()*/) {
|
if (is_single_full_instance() && !wxGetApp().obj_manipul()->is_world_coordinates()) {
|
||||||
if (!boost::starts_with(sidebar_field, "position")) {
|
center = box_trafo.translation();
|
||||||
if (boost::starts_with(sidebar_field, "scale"))
|
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
||||||
|
} else if (is_single_volume_or_modifier()) {
|
||||||
|
if (!wxGetApp().obj_manipul()->is_world_coordinates()) {
|
||||||
|
if (wxGetApp().obj_manipul()->is_local_coordinates()) {
|
||||||
|
orient_matrix = get_bounding_box_in_current_reference_system().second;
|
||||||
|
orient_matrix.translation() = Vec3d::Zero();
|
||||||
|
} else {
|
||||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
||||||
else if (boost::starts_with(sidebar_field, "rotation")) {
|
center = box_trafo.translation();
|
||||||
if (boost::ends_with(sidebar_field, "x"))
|
|
||||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
|
||||||
else if (boost::ends_with(sidebar_field, "y")) {
|
|
||||||
const Vec3d& rotation = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation();
|
|
||||||
if (rotation.x() == 0.0)
|
|
||||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
|
||||||
else
|
|
||||||
orient_matrix.rotate(Eigen::AngleAxisd(rotation.z(), Vec3d::UnitZ()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else if (is_single_volume() || is_single_modifier()) {
|
if (requires_local_axes()) {
|
||||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
|
||||||
if (!boost::starts_with(sidebar_field, "position"))
|
|
||||||
orient_matrix = orient_matrix * (*m_volumes)[*m_list.begin()]->get_volume_transformation().get_rotation_matrix();
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (requires_local_axes())
|
|
||||||
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
orient_matrix = (*m_volumes)[*m_list.begin()]->get_instance_transformation().get_rotation_matrix();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const Transform3d base_matrix = Geometry::assemble_transform(center);
|
||||||
|
|
||||||
if (!boost::starts_with(sidebar_field, "layer"))
|
if (!boost::starts_with(sidebar_field, "layer"))
|
||||||
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
glsafe(::glClear(GL_DEPTH_BUFFER_BIT));
|
||||||
|
@ -2033,6 +2002,8 @@ void Selection::render_sidebar_hints(const std::string& sidebar_field, bool unif
|
||||||
render_sidebar_position_hints(sidebar_field, *shader, base_matrix * orient_matrix);
|
render_sidebar_position_hints(sidebar_field, *shader, base_matrix * orient_matrix);
|
||||||
else if (boost::starts_with(sidebar_field, "rotation"))
|
else if (boost::starts_with(sidebar_field, "rotation"))
|
||||||
render_sidebar_rotation_hints(sidebar_field, *shader, base_matrix * orient_matrix);
|
render_sidebar_rotation_hints(sidebar_field, *shader, base_matrix * orient_matrix);
|
||||||
|
else if (boost::starts_with(sidebar_field, "absolute_rotation"))
|
||||||
|
render_sidebar_rotation_hints(sidebar_field, *shader, base_matrix * orient_matrix);
|
||||||
else if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size"))
|
else if (boost::starts_with(sidebar_field, "scale") || boost::starts_with(sidebar_field, "size"))
|
||||||
//BBS: GUI refactor: add uniform_scale from gizmo
|
//BBS: GUI refactor: add uniform_scale from gizmo
|
||||||
render_sidebar_scale_hints(sidebar_field, uniform_scale, *shader, base_matrix * orient_matrix);
|
render_sidebar_scale_hints(sidebar_field, uniform_scale, *shader, base_matrix * orient_matrix);
|
||||||
|
@ -3052,6 +3023,9 @@ void Selection::ensure_not_below_bed()
|
||||||
|
|
||||||
bool Selection::is_from_fully_selected_instance(unsigned int volume_idx) const
|
bool Selection::is_from_fully_selected_instance(unsigned int volume_idx) const
|
||||||
{
|
{
|
||||||
|
if (m_mode == Instance && wxGetApp().plater()->canvas3D()->get_canvas_type() == GLCanvas3D::ECanvasType::CanvasAssembleView) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
struct SameInstance
|
struct SameInstance
|
||||||
{
|
{
|
||||||
int obj_idx;
|
int obj_idx;
|
||||||
|
@ -3180,14 +3154,14 @@ void Selection::paste_objects_from_clipboard()
|
||||||
Vec3d displacement;
|
Vec3d displacement;
|
||||||
bool in_current = plate->intersects(bbox);
|
bool in_current = plate->intersects(bbox);
|
||||||
auto start_point = in_current ? bbox.center() : plate->get_build_volume().center();
|
auto start_point = in_current ? bbox.center() : plate->get_build_volume().center();
|
||||||
|
auto start_offset = in_current ? src_object->instances.front()->get_offset() : plate->get_build_volume().center();
|
||||||
if (shift_all(0) != 0 || shift_all(1) != 0) {
|
if (shift_all(0) != 0 || shift_all(1) != 0) {
|
||||||
// BBS: if multiple objects are selected, move them as a whole after copy
|
// BBS: if multiple objects are selected, move them as a whole after copy
|
||||||
if (i == 0) empty_cell_all = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)}, {bbox.size()(0)+1,bbox.size()(1)+1});
|
if (i == 0) empty_cell_all = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)}, {bbox.size()(0)+1,bbox.size()(1)+1});
|
||||||
auto instance_shift = src_object->instances.front()->get_offset() - src_objects[0]->instances.front()->get_offset();
|
auto instance_shift = src_object->instances.front()->get_offset() - src_objects[0]->instances.front()->get_offset();
|
||||||
displacement = {shift_all.x() + empty_cell_all.x()+instance_shift.x(), shift_all.y() + empty_cell_all.y()+instance_shift.y(), start_point(2)};
|
displacement = {shift_all.x() + empty_cell_all.x() + instance_shift.x(), shift_all.y() + empty_cell_all.y() + instance_shift.y(), start_offset(2)};
|
||||||
} else {
|
} else {
|
||||||
// BBS: if only one object is copied, find an empty cell to put it
|
// BBS: if only one object is copied, find an empty cell to put it
|
||||||
auto start_offset = in_current ? src_object->instances.front()->get_offset() : plate->get_build_volume().center();
|
|
||||||
auto point_offset = start_offset - start_point;
|
auto point_offset = start_offset - start_point;
|
||||||
auto empty_cell = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)}, {bbox.size()(0)+1, bbox.size()(1)+1});
|
auto empty_cell = wxGetApp().plater()->canvas3D()->get_nearest_empty_cell({start_point(0), start_point(1)}, {bbox.size()(0)+1, bbox.size()(1)+1});
|
||||||
displacement = {empty_cell.x() + point_offset.x(), empty_cell.y() + point_offset.y(), start_offset(2)};
|
displacement = {empty_cell.x() + point_offset.x(), empty_cell.y() + point_offset.y(), start_offset(2)};
|
||||||
|
|
|
@ -15,6 +15,7 @@ class Model;
|
||||||
class ModelObject;
|
class ModelObject;
|
||||||
class ModelVolume;
|
class ModelVolume;
|
||||||
class ObjectID;
|
class ObjectID;
|
||||||
|
class ModelInstance;
|
||||||
class GLVolume;
|
class GLVolume;
|
||||||
class GLArrow;
|
class GLArrow;
|
||||||
class GLCurvedArrow;
|
class GLCurvedArrow;
|
||||||
|
@ -225,6 +226,9 @@ public:
|
||||||
void remove_volumes(EMode mode, const std::vector<unsigned int>& volume_idxs);
|
void remove_volumes(EMode mode, const std::vector<unsigned int>& volume_idxs);
|
||||||
|
|
||||||
//BBS
|
//BBS
|
||||||
|
ModelVolume * get_selected_single_volume(int &out_object_idx, int &out_volume_idx) const;
|
||||||
|
ModelObject * get_selected_single_object(int &out_object_idx) const;
|
||||||
|
const ModelInstance * get_selected_single_intance() const;
|
||||||
void add_curr_plate();
|
void add_curr_plate();
|
||||||
void add_object_from_idx(std::vector<int>& object_idxs);
|
void add_object_from_idx(std::vector<int>& object_idxs);
|
||||||
void remove_curr_plate();
|
void remove_curr_plate();
|
||||||
|
@ -326,20 +330,17 @@ public:
|
||||||
const std::pair<Vec3d, double> get_bounding_sphere() const;
|
const std::pair<Vec3d, double> get_bounding_sphere() const;
|
||||||
|
|
||||||
void setup_cache();
|
void setup_cache();
|
||||||
|
|
||||||
void translate(const Vec3d& displacement, TransformationType transformation_type);
|
void translate(const Vec3d& displacement, TransformationType transformation_type);
|
||||||
void move_to_center(const Vec3d& displacement, bool local = false);
|
void move_to_center(const Vec3d& displacement, bool local = false);
|
||||||
void rotate(const Vec3d& rotation, TransformationType transformation_type);
|
void rotate(const Vec3d& rotation, TransformationType transformation_type);
|
||||||
void flattening_rotate(const Vec3d& normal);
|
void flattening_rotate(const Vec3d& normal);
|
||||||
[[deprecated("Only used by GizmoObjectManipulation")]]
|
|
||||||
void scale_legacy(const Vec3d& scale, TransformationType transformation_type);
|
|
||||||
void scale(const Vec3d& scale, TransformationType transformation_type);
|
void scale(const Vec3d& scale, TransformationType transformation_type);
|
||||||
#if ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
#if ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
||||||
void scale_to_fit_print_volume(const BuildVolume& volume);
|
void scale_to_fit_print_volume(const BuildVolume& volume);
|
||||||
#else
|
#else
|
||||||
void scale_to_fit_print_volume(const DynamicPrintConfig& config);
|
void scale_to_fit_print_volume(const DynamicPrintConfig& config);
|
||||||
#endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
#endif // ENABLE_ENHANCED_PRINT_VOLUME_FIT
|
||||||
void scale_and_translate(const Vec3d& scale, const Vec3d& world_translation, TransformationType transformation_type);
|
void scale_and_translate(const Vec3d &scale, const Vec3d &world_translation, TransformationType transformation_type);
|
||||||
void mirror(Axis axis, TransformationType transformation_type);
|
void mirror(Axis axis, TransformationType transformation_type);
|
||||||
|
|
||||||
void translate(unsigned int object_idx, const Vec3d& displacement);
|
void translate(unsigned int object_idx, const Vec3d& displacement);
|
||||||
|
@ -351,6 +352,7 @@ public:
|
||||||
//BBS: add partplate related logic
|
//BBS: add partplate related logic
|
||||||
void notify_instance_update(int object_idx, int instance_idx);
|
void notify_instance_update(int object_idx, int instance_idx);
|
||||||
// BBS
|
// BBS
|
||||||
|
EMode get_volume_selection_mode(){ return m_volume_selection_mode;}
|
||||||
void set_volume_selection_mode(EMode mode) { if (!m_volume_selection_locked) m_volume_selection_mode = mode; }
|
void set_volume_selection_mode(EMode mode) { if (!m_volume_selection_locked) m_volume_selection_mode = mode; }
|
||||||
void lock_volume_selection_mode() { m_volume_selection_locked = true; }
|
void lock_volume_selection_mode() { m_volume_selection_locked = true; }
|
||||||
void unlock_volume_selection_mode() { m_volume_selection_locked = false; }
|
void unlock_volume_selection_mode() { m_volume_selection_locked = false; }
|
||||||
|
@ -358,11 +360,11 @@ public:
|
||||||
void erase();
|
void erase();
|
||||||
|
|
||||||
void render(float scale_factor = 1.0);
|
void render(float scale_factor = 1.0);
|
||||||
//BBS: GUI refactor: add uniform scale from gizmo
|
|
||||||
void render_sidebar_hints(const std::string& sidebar_field, bool uniform_scale);
|
|
||||||
#if ENABLE_RENDER_SELECTION_CENTER
|
#if ENABLE_RENDER_SELECTION_CENTER
|
||||||
void render_center(bool gizmo_is_dragging);
|
void render_center(bool gizmo_is_dragging);
|
||||||
#endif // ENABLE_RENDER_SELECTION_CENTER
|
#endif // ENABLE_RENDER_SELECTION_CENTER
|
||||||
|
//BBS: GUI refactor: add uniform scale from gizmo
|
||||||
|
void render_sidebar_hints(const std::string& sidebar_field, bool uniform_scale);
|
||||||
|
|
||||||
bool requires_local_axes() const;
|
bool requires_local_axes() const;
|
||||||
|
|
||||||
|
@ -405,7 +407,8 @@ private:
|
||||||
void set_bounding_boxes_dirty() {
|
void set_bounding_boxes_dirty() {
|
||||||
m_bounding_box.reset();
|
m_bounding_box.reset();
|
||||||
m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset();
|
m_unscaled_instance_bounding_box.reset(); m_scaled_instance_bounding_box.reset();
|
||||||
m_full_unscaled_instance_bounding_box.reset(); m_full_scaled_instance_bounding_box.reset();
|
m_full_unscaled_instance_bounding_box.reset();
|
||||||
|
m_full_scaled_instance_bounding_box.reset();
|
||||||
m_full_unscaled_instance_local_bounding_box.reset();
|
m_full_unscaled_instance_local_bounding_box.reset();
|
||||||
m_bounding_box_in_current_reference_system.reset();
|
m_bounding_box_in_current_reference_system.reset();
|
||||||
m_bounding_sphere.reset();
|
m_bounding_sphere.reset();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue