Antworten auf deine Fragen:
Neues Thema erstellen

Py4D Austauschthread

nux95

Developer, C4D Betatester

AW: Py4D Austauschthread

Klar gibts da ein Beispiel. Nähmlich in der neuesten Python Documentation unter "Examples" und dann "plugins/Py-LiquidPainter". ;-)

Cheers,
 

Cyres90

Noch nicht viel geschrieben

AW: Py4D Austauschthread

Danke, nun folgendes Problem:
Per Mausklick wird nun ein Objekt genau auf dem Curser ausgerichtet. Das ganze funkioniert auch, wenn ich die Maus ziehe (Mousedrag), jedoch werden dabei nicht die Koordinaten aktualisiert. Ich probiere jetzt bestimmt schon seit einer geschlagenen Stunde rum, anbei die Projektdatei.

Frage 1:
Wie kann ich bei diesem MouseDrag die Koordinaten interaktiv anzeigen lassen?


Ich habe mir im weiteren nun folgendes überlegt:
ich möchte sozusagen einen Strahl von der Kamera Richtung Curser schicken. Falls er ein Objekt schneidet, soll er die Normale der Fläche und den Schnittpunkt zurückgeben. Falls in einer vorher festgelegten Distanz keine Kollision stattgefunden hat, soll der Schnittpunkt mit der Koordinatenachse ausgegeben werden. (In der Perspektive die XZ-Ebene, in den Parallelperspektiven die jeweiligen, Orthogonal zur Blickrichtung stehenden, Ebenen)
Ich hoffe, dies ist verständlich beschrieben.

Meine Idee
Über die Werkzeug-GUI kann man leicht die Tiefe bestimmen (im Folgenden als mz bezeichnet), man erhält also einen Vektor (mx, my, mz), den man mit dem SW-Befehl in Koordinaten umwandeln kann. Ein Strahl wäre somit also realisiert.

Frage 2:
Würde man mit einem Solchen Prinzip ein Schnittpunkt mit einer Fläche bzw. mit den Welt-"Ebenen" auslesen und ggf auch eine Flächennormale?

Ich hoffe, jemand weiß Rat *zu nux schiel* ;)


Plugin:
 
Zuletzt bearbeitet:

nux95

Developer, C4D Betatester

AW: Py4D Austauschthread

Cyres90 schrieb:
Frage 1:
Wie kann ich bei diesem MouseDrag die Koordinaten interaktiv anzeigen lassen?
Wie meinstn des ?

Cyres90 schrieb:
ich möchte sozusagen einen Strahl von der Kamera Richtung Curser schicken.
Cyres90 schrieb:
Würde man mit einem Solchen Prinzip ein Schnittpunkt mit einer Fläche bzw. mit den Welt-"Ebenen" auslesen und ggf auch eine Flächennormale?

nux95 schrieb:
Zum ermitteln der Position auf dem Objekt kannst du die GeRayCollider Klasse verwenden.
;)
Cyres90 schrieb:
Meine Idee
Über die Werkzeug-GUI kann man leicht die Tiefe bestimmen (im Folgenden als mz bezeichnet), man erhält also einen Vektor (mx, my, mz), den man mit dem SW-Befehl in Koordinaten umwandeln kann. Ein Strahl wäre somit also realisiert.
Ne, damit haste nur nen Punkt im Raum definiert. (Wenn man davon absieht dass ein Vektor ein Strahl ist, haha)
Momentan hast'e ja ne Tiefe mz = 1000.0 eingestellt.

Cyres90 schrieb:
Muss dich loben :D Zum einen bist du ja selber schon sehr weit gekommen, zum anderen fragen viele einfach bringen aber kein beispiel von ihrem problem. :hmpf:

Also ich hab das mal eingebaut mit dem GeRayCollider. Allerdings hab ich noch nicht herausgefunden wie man einstellen kann dass der Ray auch die Rotation und Skalierung des Objekts erkennt. Verfolge dazu mal diesen Thread, ich hoffe auch da eine Antwort vom her Rath zu bekommen. ;)


Ich hab einfach mal das Nächste Objekt zum bereits selektierten gewählt, auf dem das selektierte ausgerichtet wird.
Die Kollisionserkennung könntest du noch auf Klonobjekte etc. ausweiten, nur so als Tipp :)
(Da Funktioniert MakeEditable nicht) [obj.GetChache() ;) ]

http://www.mediafire.com/?52dyk0ml5600o

Cheers,

PS: Übertreibs nicht mit den Updates :D
Einmal DrawViews in der while reicht vollkommen aus. EventAdd is unnötig.
 
Zuletzt bearbeitet:

Cyres90

Noch nicht viel geschrieben

AW: Py4D Austauschthread

Wie meinstn des ?

Die Koordinaten werden im Koordinatenmanager und im Attributmanager ja angezeigt, während des verschiebevorgang beim Mousedrag sollen diese aber auch aktualisiert werden.


Ne, damit haste nur nen Punkt im Raum definiert. (Wenn man davon absieht dass ein Vektor ein Strahl ist, haha)
Momentan hast'e ja ne Tiefe mz = 1000.0 eingestellt.

Mir hat deine Art und Weise sehr gefallen, einfach die Position in unterschiedlicher Distanz 2 mal auszulesen :)

Muss dich loben :D Zum einen bist du ja selber schon sehr weit gekommen, zum anderen fragen viele einfach bringen aber kein beispiel von ihrem problem. :hmpf:

Danke für die Blumen :D

Also ich hab das mal eingebaut mit dem GeRayCollider. Allerdings hab ich noch nicht herausgefunden wie man einstellen kann dass der Ray auch die Rotation und Skalierung des Objekts erkennt. Verfolge dazu mal diesen Thread, ich hoffe auch da eine Antwort vom her Rath zu bekommen. ;)

Danke für den Link, ich bin heute nacht, als ich den RayCollider zufällig entdeckt habe, auf ähnliche Probleme gestoßen. Das problem ist, dass das RayObjekt immer geprüft wird, als wäre es im Mittelpunkt. Ich werde mal versuchen die Vektoren des ray.Intersect durch die inverse matrix des RayObjektes zu jagen, sozusagen als interne verschiebung des RayObjektes, nur dass der RayStrahl anstelle des RayObjektes verschoben wird.


Ich hab einfach mal das Nächste Objekt zum bereits selektierten gewählt, auf dem das selektierte ausgerichtet wird.
Die Kollisionserkennung könntest du noch auf Klonobjekte etc. ausweiten, nur so als Tipp :)
(Da Funktioniert MakeEditable nicht) [obj.GetChache() ;) ]

Alles zu seiner Zeit, das Auto wurde auch erst nach dem Rad erfunden ;)

Ich habe momentan übrigens das Plugin dahingehend erweitert, dass mehrere Objekte gleichzeitig ausgerichtet werden können. Außerdem habe ich die Art der Positionierung umgestellt, da es Probleme gab, wenn das Objekt ein Unterobjekt eines verschobenen anderen Objektes war. (Einfach die Globale Matrix gesetzt ^^)

Cheers
 

Cyres90

Noch nicht viel geschrieben

AW: Py4D Austauschthread

Mein og. Problem konnte ich folgendermaßen lösen:

PHP:
import c4d
from c4d.utils import GeRayCollider
c4d.CallCommand(1024314)

def ZeroAxe(op):        # Setzt die Objektachse auf den Weltursprung
    mg = op.GetMg()
    op.SetMg(c4d.Matrix())
    count = op.GetPointCount()
    for id in xrange(count):
        pos = op.GetPoint(id)
        pos *= mg
        op.SetPoint(id,pos)
        op.Message(c4d.MSG_UPDATE)

def MakeEditable(op):
    if op is None:
        return
    if not isinstance(op,c4d.BaseObject):
        return
    if op.CheckType(c4d.Opolygon) | op.CheckType(c4d.Ospline):
        return op

    op = [op.Get*****()]
    doc = c4d.documents.BaseDocument()
    doc.InsertObject(op[0],None,None)
    op = c4d.utils.SendModelingCommand(
                              command = c4d.MCOMMAND_MAKEEDITABLE,
                              list = op,
                              doc = doc )
    return op[0]

def main():
    op = doc.GetActiveObject()
    if not op:
        print "No object selected."
        return
    op = MakeEditable(op)
    ZeroAxe(op)
    
    ray = GeRayCollider()
    ray.Init(op)
    
    v1  = c4d.Vector(100,10,50)
    v2  = c4d.Vector.GetNormalized(c4d.Vector(-1,0.5,0.5))
        
    print "Startvektor:             ",v1
    print "Richtungsvektor:     ",v2
    print
    
    if ray.Intersect(v1, v2, 5000) == False: return
    sct = ray.GetNearestIntersection()
    
    print "Kollisionsposition:    ", sct["hitpos"]
    print "KollisionsflächenID: ", sct["face_id"]
    print "Kollisionsnormale:    ", c4d.Vector.GetNormalized(sct["f_normal"])
    print "Distanz:                   ", sct["distance"]

main()

Meine Frage dazu: Gibt es eine einfachere Möglichkeit, die Objektachse auf dem Weltursprung auszurichten?
 
Zuletzt bearbeitet:

nux95

Developer, C4D Betatester

AW: Py4D Austauschthread

Nope, das ist die einfachste Methode ;-)
Aber mach das MSG_UPDATE aus der For-schleife raus und setz es danach ein.
 

Cyres90

Noch nicht viel geschrieben

AW: Py4D Austauschthread

Okay, leuchtet ein, man muss Scripte ja nicht unnötig langsamer machen :D

Weißt du denn eine möglichkeit zu dem Plugin, die Koordinaten interaktiv anzeigen zu lassen?
 

nux95

Developer, C4D Betatester

AW: Py4D Austauschthread

Benutze BaseDraw'ing. ;)
(Siehe Py4D Docs: class BaseDraw)

Damit du nicht jedes mal Cinema 4D neustarten musst, um ein Ergebnis zu sehen, kannst'e mein DrawHelper Plugin benutzen. :D
Py-DrawHelper - CGSociety

Cheers,

//edit:
Hm, sehe gerade dass es anscheinend nicht funktioniert, Text zu "drawen".
Mal sehen wie ich das lösen kann.
//edit:
Ok, habe es herausgefunden. :)
- GeClipMap erstellen, Text "reinmalen"
- BaseDraw.DrawTexture(myClipMap)
- feddisch ;)
 
Zuletzt bearbeitet:

Cyres90

Noch nicht viel geschrieben

AW: Py4D Austauschthread

Ich verstehe gerade nicht ganz, wie du das meinst? was ist eine GeClipMap? Kannst du den Code posten?

Hast du was neues zu deinen Fragen im Plugin-Cafe-Board rausgefunden?
 

nux95

Developer, C4D Betatester

AW: Py4D Austauschthread

Cyres90 schrieb:
was ist eine GeClipMap?
Schau doch in den Py4D Docs, was eine GeClipMap is'. :p

Der Code müsste ungefähr so aussehen, ist jetzt nur aus den Finger gezogen, könnte auch Syntaxfehler enthalten:
PHP:
def Vec2Tup(vec):
    return vec.x, vec.y, vec.z
bd.SetMatrix_Screen(op)
clpmap = GeClipMap()
clpmap.Init(100,200) # width, height
pos = Vec2Tup(obj.GetAbsPos())
for i, e in enumerate(zip(pos, ("x", "y", ",z"))):
    clpmap.Text(5, i * 15, e[1] + ": " + str(e[0])) # x, y, text
bmp = clpmap.GetBitmap()
bd.DrawTexture(c4d.Vector(0,0,0), bmp) # pos, bitmap (nicht ganz sicher ob die argumente stimme)
Cyres90 schrieb:
Hast du was neues zu deinen Fragen im Plugin-Cafe-Board rausgefunden?
Leider nicht.

Cheers,
 

Cyres90

Noch nicht viel geschrieben

AW: Py4D Austauschthread

Hmm, ich glaub, da muss ich mich noch etwas tiefer einarbeiten um alles zu verstehen, probiere ich mal bei gelegenheit aus ;)

Ich habe derweil ein anderes Script gebaut. Hoffe, es macht keinem was aus, es hier zu posten, in der Hoffnung, jemand ließt korrektur ^^

Das Script tut folgendes:
Es ließt alle Objekte in der Szene aus und gibt sie in einer Liste wieder.
Jedes Objekt hat drei dict-Einträge:
- Object (BaseObject)
- VisInEdit (Bool)
- VisInRend (Bool)

Die letzten beiden Boole geben an, ob das Objekt in der Szene angezeigt wird und entspricht dabei den beiden Punkten im Objekt Manager, wobei der graue Punkt hierarisch berücksichtig wird.


Script: Bibliothek.py
PHP:
"""
Bibliothek.py

GetAllObjects

Copyright: Cyres
Written for CINEMA 4D R12.043

LastModified: 7.06.2011
"""

def GetAllObjects():

    def DirectChildren(ObjList,Obj,VisInEdit,VisInRend):
        if Obj.GetDown():
            Obj = Obj.GetDown()
            VisInEditUp = VisInEdit
            VisInRendUp = VisInRend
            if Obj[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] == 0:VisInEdit = True
            elif Obj[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] == 1:VisInEdit = False
            if Obj[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] == 0:VisInRend = True
            elif Obj[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] == 1:VisInRend = False
            ObjList = Append(ObjList,Obj,VisInEdit,VisInRend)
            ObjList = DirectChildren(ObjList,Obj,VisInEdit,VisInRend)
            ObjNext = Obj
            while Obj.GetNext():
                Obj = Obj.GetNext()
                if Obj[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] == 0:VisInEdit = True
                elif Obj[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] == 1:VisInEdit = False
                else:VisInEdit = VisInEditUp
                if Obj[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] == 0:VisInRend = True
                elif Obj[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] == 1:VisInRend = False
                else:VisInEdit = VisInRendUp
                ObjList = Append(ObjList,Obj,VisInEdit,VisInRend)
                ObjList = DirectChildren(ObjList,Obj,VisInEdit,VisInRend)
        return ObjList

    def Append(ObjList,Obj,VisInEdit,VisInRend):
        Object = {"Object":    Obj,
                  "VisInEdit": VisInEdit,
                  "VisInRend": VisInRend}
        ObjList.append(Object)
        return ObjList
    
    import c4d

    ObjList = list()
    doc = c4d.documents.GetActiveDocument()
    if not doc.GetFirstObject(): return
    Obj = doc.GetFirstObject()
    if Obj[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] == 1:VisInEdit = False
    else:VisInEdit = True
    if Obj[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] == 1:VisInRend = False
    else:VisInRend = True
    ObjList = Append(ObjList,Obj,VisInEdit,VisInRend)
    ObjList = DirectChildren(ObjList,Obj,VisInEdit,VisInRend)
    while Obj.GetNext():
        Obj = Obj.GetNext()
        if Obj[c4d.ID_BASEOBJECT_VISIBILITY_EDITOR] == 1:VisInEdit = False
        else:VisInEdit = True
        if Obj[c4d.ID_BASEOBJECT_VISIBILITY_RENDER] == 1:VisInRend = False
        else:VisInRend = True
        ObjList = Append(ObjList,Obj,VisInEdit,VisInRend)
        ObjList = DirectChildren(ObjList,Obj,VisInEdit,VisInRend)

    return ObjList

Programm:
PHP:
import c4d
import Bibliothek
c4d.CallCommand(1024314)

ObjLib = Bibliothek.GetAllObjects()
for Obj in ObjLib:
    print Obj["Object"].GetName()
    print Obj["VisInEdit"]
    print Obj["VisInRend"]
 
N

neosun

Guest

AW: Alle selektierten Objekte | GetActiveObjects(doc)

Eine Funktion, bzw 2, die eine benötigt die andere, welche alle selektierten Objekte einer Szene in eine list packt.

Code:
def GetHNext(op):
    if not op: return
    if op.GetDown(): return op.GetDown()
    while not op.GetNext() and op.GetUp():
        op = op.GetUp()
    return op.GetNext()

def GetActiveObjects(doc):
    import c4d
    lst = list()
    op = doc.GetFirstObject()
    while op:
        if op.GetBit(c4d.BIT_ACTIVE) == True: lst.append(op)
        op = GetHNext(op)
    return lst
cheers, nux
Frage dazu, wenn ich diese Liste mit einer for obj in liste: outLink=obj
Schleife durchgehe und sagen wir z.B. den Namen ändern will, wird immer nur
das letzte Objekt verändert. Hätte nun aber gerne den Effekt des Hierarchie
Nodes, also das jedes Objekt angesprochen wird und nicht nur das Letzte aus
der Liste.
Das mit dem Namen wäre nur ein Beispiel, würde ab dieser Stelle gerne mit
Nodes weiterarbeiten. Der Python Code hätte also den Nutzen eines besseren
Hierarchie Nodes der auch Childs beachtet. Gibts da eine Möglichkeit?

Gruß
 

nux95

Developer, C4D Betatester

AW: Py4D Austauschthread

Du sprichst von einem XPresso Node ?
Oh man keine Lust das mit worten zu erklären, hier isn Bild das soltle dir zeigen was das problem ist. ^^
 
N

neosun

Guest

AW: Py4D Austauschthread

Hey,
ja ging um Nodes, dachte drei mal erwähnen wäre eindeutig genug :p.
Danke schon mal für die Erklärung wie mit tausend Worten ;), sowas in der
Art dachte ich mir schon. Dann muss ich wohl versuchen die Liste in eine
'In-/Excludelist' zu wandeln und diese dann abzuarbeiten.

Gruss
 

nux95

Developer, C4D Betatester

AW: Py4D Austauschthread

@nesoun: Uh, haha. Irgendwie verpeilt :D Naia, es gibt schon einen weg, aber der is etwas umständlich un erfordert mehrere Nodes. Wenn du die allerdings in eine XGroup packst gehts eigentlich. Muss selber aber nochmal kurz ausprobieren bevor ich schlau daher red. ;)

Und wie würdest du einen IteratorNode in COFFEE erstellen, mp5 ? ;)
 
N

neosun

Guest

AW: Py4D Austauschthread

Hey,
danke, aber musst du nicht, hab das mit der IncludeListe geregelt (siehe Anhang).
Und die Liste war auch schnell erstellt dank der Python SDK und deinem Code ;)

Gruß
 

nux95

Developer, C4D Betatester

AW: Py4D Austauschthread

@neosun: Dann ist gut. :)

Iterator Node aus XPresso benutzen
Die Idee hatte ich auch bin aber grad am überlegen wie man das effizient löst. Der Iterator node sollte ja nich bis 100000 durchlaufen wenn zb nu 15 objekte im OM sind..
ne eigene Schleife per COFFEE-Node erstellen.
Und wie willst du machen dass du innerhalb der schleife den output weitergibts ? Das hat Neosun ja in python versucht.
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
118.614
Beiträge
1.538.351
Mitglieder
67.525
Neuestes Mitglied
mgtaucher
Oben