Ankündigung

Einklappen
Keine Ankündigung bisher.

Object im Script deselektieren

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Python Object im Script deselektieren

    Hallo,

    ich schreibe gerade mein erstes Script. Zugegegen, die ganze Sache ist sehr schwer für mich und undurchsichtig. Also bitte habt Nachsicht für ein wahrscheinlich simples Problem. Da ich häufig Teile eines Objekts kopiere und wiederverwende ist es auf dauer doch nervig immer die Faces zu selectieren, zu duplizieren anschließend über Taste "P" zu einem extre Objekt zu wandeln, dann in den Objektmodus wechseln und dann noch das neue Objekt anzuwählen. Daher wollte ich ein Script schreiben dass das alles automatisch macht.

    So, bis zum Objektmode bin ich gekommen. Ich wähle meine Faces aus, lass das script laufen und es erledigt alles. Nur jetzt im Objektmode angekommen krieg ich es nicht gebacken, das erste Objekt (also das Originale) zu deselektieren, damit automatisch nur das neue ausgewählt ist. Denn in 99,9 Prozent der Fälle will ich ja nur mit dem neuen Objekt was anstellen. Ich hab das Script mal unten hingeschrieben, aber wie gesasgt hab ich keine Ahnung wie ich das alte objekt deselektieren kann.


    import bpy
    bpy.ops.mesh.duplicate_move(MESH_OT_duplicate={"mo de":1}, TRANSFORM_OT_translate={"value"0, 0, 0), "constraint_axis"False, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point"0, 0, 0), "snap_align":False, "snap_normal"0, 0, 0), "gpencil_strokes":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False, "use_accurate":False})

    bpy.ops.mesh.separate(type='SELECTED')
    bpy.ops.object.mode_set(mode='OBJECT')
    Zuletzt geändert von gopper0815; 17.05.2018, 19:07.

  • #2
    Bitte den Code in [code][/code] einschließen.

    Kommentar


    • #3
      Wie wäre es damit?

      Code:
      import bpy
      
      ob1 = set(bpy.data.objects)
      
      bpy.ops.mesh.duplicate_move(MESH_OT_duplicate={"mode":1}, TRANSFORM_OT_translate={"value":(0, 0, 0), "constraint_axis":(False, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False, "use_accurate":False})
      
      bpy.ops.mesh.separate(type='SELECTED')
      bpy.ops.object.mode_set(mode='OBJECT')
      bpy.ops.object.select_all(action='DESELECT')
      
      ob2 = set(bpy.data.objects)
      new = ob2.difference(ob1).pop()
      
      bpy.ops.object.select_all(action='DESELECT')
      bpy.context.scene.objects.active = new
      new.select = True

      Kommentar


      • #4
        Ja das ist genau das was ich wollte. Auch wenn ich das Script noch nicht verstehe und ich mir das noch genau anschauen muss, schon mal vielen Dank. Warum tu ich mir nur so schwer damit? Man braucht wohl wirklich Talent für sowas. Ist vielleicht ne blöde Frage, aber ist es sehr hilfreich, wenn man sich Python allgemein etwas beibringt, oder ist das in Blender so speziell, dass man damit nicht viel anfangen kann?
        Zuletzt geändert von gopper0815; 17.05.2018, 19:19.

        Kommentar


        • #5
          Meiner Erfahrung nach gibt es wenig blöde Fragen aber eine Menge blöder Antworten.

          Bei mir war es tatsächlich ähnlich wie wohl gerade bei dir.
          Ich habe Python gelernt um damit in Blender etwas anfangen zu können. Aus dieser Erfahrung kann ich sagen, dass gute Kenntnisse in Python auf jeden Fall hilfreich, tatsächlich sogar notwendig sind, um in Blender weiter zu kommen. Da Python, zumindest in den Grundzügen, relativ einfach zu erlernen ist, ist das erst mal kein Problem.
          Die Blender-Python-API ist dann noch mal ein anderes Thema, insbesondere die dahinter liegenden Denkschemata und Paradigmen, die eben sehr an die Datenstrukturen und -handling von Blender angelehnt sind. Intern ist da vieles "logisch", was einem als Neuling aber überhaupt nicht einleuchtet und auch nicht "zu erraten" ist.
          Da hat sich mit den Jahren was die Dokumentation und Webseiten angeht aber viel verbessert und mit StackOverflow hat man eine Ressource, die, bei genügender Hartnäckigkeit, wohl die meisten Probleme lösen hilft. Trotzdem braucht es Zeit und Übung, um sich Schritt für Schritt hinein zu finden.

          Als Beispiel vielleicht ein paar Erläuterungen zum Script:

          ob1 = set(bpy.data.objects)
          Eine Mischung aus Python und Blender-API.
          bpy.data.objects liefert eine Liste aller aktuellen Objekte in der Szene. Diese Liste wandelt set (ein Python-Befehl) in eine Menge um, die unter dem Namen ob1 gespeichert wird. Das mache ich, um später einfach eine Differenz zweier Mengen bilden zu können, was mit Listen nicht so elegant geht.
          Nachdem später das neue Objekt dupliziert wurde mache ich

          ob2 = set(bpy.data.objects)
          Wie oben, nur das ob2 nun auch das neu erzeugte Objekt enthält.

          new = ob2.difference(ob1).pop()
          difference ist ein Python-Befehl für Mengen und gibt den Unterschied zurück, der hier nur aus dem neu erzeugten Objekt besteht. Das zurückgegebene Objekt ist ebenfalls eine Menge, aus der pop() (ein Python-Befehl u.a. für Mengen, bei Listen wirft es das letzte Element aus, aber Mengen sind nicht sortiert) irgendein Objekt der Menge ausgibt und die Menge um dieses Objekt reduziert. Da die Differenzmenge nur aus dem neuen Objekt besteht wird dieses zurück gegeben und unter dem Namen new gespeichert.
          Das Ganze dient also dazu das neu erzeugte Objekt zu fassen zu bekommen.

          bpy.ops.object.select_all(action='DESELECT')
          Das ist ein API-Befehl um alles zu deselektieren, den ich über StackOverflow (google: blender python deselect everything) gefunden habe.
          Ich sehe gerade, das der Befehl zweimal im Skript vorkommt, einmal sollte eigentlich reichen.

          bpy.context.scene.objects.active = new
          Auch ein API Befehl in typischer "Blender interner Logik". Ob ein Objekt aktiv ist oder nicht wird im "context" der Szene gespeichert. "Context" ist für Blender sehr wichtig, weil die Ausführung vieler Operationen davon abhängt, wo man gerade mit der Maus ist (3D-Fenster, Menüs...) und in welchen Zustand sich das jeweilige Objekt befindet (Edit-Mode, Object-Mode..). In der Hierarchie gibt es also den context, innerhalb dessen die Szene, dann die dort vorhanden Objekte von denen immer nur eines aktiv sein kann. Diesen "Objekt ist aktiv"-Slot kann man nun ein Objekt zuweisen, hier also das neu erzeugte Objekt.

          new.select = True
          Da es mehrere selektierte Objekte geben kann wird dieser Zustand nicht wie der des aktiven Objekts im Context der Szene gespeichert, sondern ist eine Eigenschaft der Objekte selbst und kann dort auch gesetzt werden.
          "new.active = True" geht hingegen nicht, da Objekte keine "active" Eigenschaft haben (was auch Sinn macht, da Blender "hinter den Kulissen" einem anderen, möglicherweise aktiven Objekt, diesen Zustand entziehen müsste, da es ja immer nur ein aktives Objekt geben darf. Solche Arbeiten hinter den Kulissen werden typischerweise, wenn nötig, von Operatoren übernommen, also von der bpy.ops Hierarchie, was aus Sicht des Programmierers Vor- und Nachteile haben kann).
          Zuletzt geändert von alias_ludi; 17.05.2018, 23:10.

          Kommentar


          • #6
            Vielen Dank für die ausführliche Erklärung. Jetzt ergibt das Ganze mehr Sinn. Dann werde ich mich wohl tiefer in Python reinarbeiten, um damit meine arbeit letztendlich zu erleichtern.

            Kommentar

            Lädt...
            X