 
  Wed, 06/10/2009 - 17:45
Hi,
I'm just starting to dive into the wonders of OCAF ( I like what I see!  )  & the salome GEOM module ( thanks Sioutis! ) in pythonOCC.
I've made an example where 2 parametric boxes are booleaned ( intersection ).
All is good, except that I would like the TPrsStd_AISPresentation to update themselves.
I've got a class Parameters that loop through the solvers when an parameter is changed.
This works just perfect, except that I have to register the following callback to get a visual update of the geometry.
My question is: what can I do such that the TPrsStd_AISPresentation objects ( prs1-3 ) and the TPrsStd_AISViewer ( viewer ) update when the solvers are triggered.
The objective is to just register a presentation of an object ( register_presentation ) and be done.
Many thanks in advance, the GEOM module really is pretty incredible!
Cheers,
-jelle
   def update():
        prs1.Update()
        prs2.Update()
        prs3.Update()
        viewer.Update()
        display.FitAll()
parameters.add_callback(update)
from __future__ import with_statement
from OCC.GEOMImpl import *
from OCC.SGEOM import *
from OCC.BRep import *
from OCC.gp import *
from OCC.TDF import *
from OCC.Utils.Topology import Topo
from OCC.Display.wxSamplesGui import start_display, display, add_function_to_menu, add_menu
from OCC.TPrsStd import *
from OCC.TNaming import *
import time
#===============================================================================
# SETUP
#===============================================================================
RESULT_LABEL = 2
# Create engine
docId = 100
myEngine = GEOMImpl_Gen()
engine = myEngine.GetEngine()
doc_h = myEngine.GetDocument(docId)
doc   = doc_h.GetObject()
# get access to operations
prim_operations = myEngine.GetI3DPrimOperations(docId)
basic_operations = myEngine.GetIBasicOperations(docId)
bool_operations = myEngine.GetIBooleanOperations(docId)
display.EnableAntiAliasing()
#===============================================================================
# UTILITIES
#===============================================================================
class operation(object):
    '''
    raises an assertion error when IsDone() returns false, with the error specified in error_statement
    '''
    def __init__(self, operation):
        self.operation = operation
    def __enter__(self):
        print 'start operation'
        self.operation.StartOperation()
    def __exit__(self, type, value, traceback):
        print 'finish operation'
        self.operation.FinishOperation()
        if not self.operation.IsDone():
            error_code = self.operation.GetErrorCode()
            raise AssertionError('did not complete operation.\nused operation class: %s \nerror code: %s' % (self.operation.__class__, error_code) )
def to_string(_str):
    from OCC.TCollection import TCollection_AsciiString as String
    return String(_str)
def to_param(x):
    return GEOM_Parameter(x)
class Parameters(object):
    def __init__(self, engine, docId):
        object.__setattr__(self, 'engine', engine)
        object.__setattr__(self, 'docId', docId)
        object.__setattr__(self, 'solvers', [])
        object.__setattr__(self, 'callbacks', [])
    def add_solver(self, solver):
        assert isinstance( solver, GEOM_Solver), '%s is not a GEOM_Solver instance' % ( solver.__class__ )
        self.solvers.append(solver)
    def add_callback(self, call):
        if callable(call):
            self.callbacks.append(call)
        else:
            raise TypeError('%s is not a callable object' % ( call.__class__ ) )
    def __setattr__(self, name, value):
        # if an attribute is a numerical value ( integer or float )
        # than its considered to be a parameter
        # hence, the interpreter constant is updated
        # and all solvers that have been added are updated
        if isinstance(value, int) or isinstance(value, float):
            print 'got numerical value', value
        else:
            raise TypeError('an paramter ( that is an attribute of the class Parameters ) is either a float or integer')
        object.__setattr__(self, name, value)
        docId = object.__getattribute__(self, 'docId')
        self.engine.SetInterpreterConstant( docId,
                                             to_string(name),
                                              value)
        for solv in self.solvers:
            seq = TDF_LabelSequence()
            print 'calling solver:', solv.__class__
            solv.Update(docId, seq)
        for call in self.callbacks:
            print 'calling callback:', call
            call()
    def __getattribute__(self, name):
        attr = object.__getattribute__(self, name)
        if isinstance(attr, int) or isinstance(attr, float):
            print 'parameter: %s value: %s' % (name, attr)
            return to_param(to_string(name))
        else:
            return attr
def print_vertices(shape):
    for i,v in enumerate(Topo(shape).vertices()):
        print 'Vertex: %s Coord: %s' % ( i, BRep_Tool().Pnt(v).Coord())
def register_presentation(geomObject):
    result_label = geomObject.GetLastFunction().GetObject().GetEntry().FindChild(RESULT_LABEL)
    prs_main = TPrsStd_AISPresentation().Set(result_label, TNaming_NamedShape().GetID()).GetObject()
    prs_main.Display(True)
    return prs_main
#===============================================================================
# EXAMPLE
#===============================================================================
def example_parametric_box(blah):
    parameters = Parameters(engine, docId)
    parameters.add_solver(prim_operations.GetSolver())
    parameters.add_solver(basic_operations.GetSolver())
    parameters.add_solver(bool_operations.GetSolver())
    # box 1
    parameters.depth    = 12
    parameters.height   = 70
    parameters.width    = 12
    parameters.depth_a  = 0
    parameters.height_a = 0
    parameters.width_a  = 0
    # box 2
    parameters.lower  = -100
    parameters.upper  = 100
    parameters.fixed_height_lower = 0
    parameters.fixed_height_higher = 10
    with operation(basic_operations):
        pnt1 = basic_operations.MakePointXYZ(parameters.width,
                                              parameters.depth,
                                               parameters.height)
        pnt1.GetObject().SetName("point 1")
        pnt2 = basic_operations.MakePointXYZ(parameters.width_a,
                                              parameters.depth_a,
                                               parameters.height_a)
        pnt2.GetObject().SetName("point 2")
        pnt3 = basic_operations.MakePointXYZ(parameters.lower,
                                              parameters.lower,
                                               parameters.fixed_height_lower)
        pnt3.GetObject().SetName("point 3")
        pnt4 = basic_operations.MakePointXYZ(parameters.upper,
                                              parameters.upper,
                                               parameters.fixed_height_higher)
        pnt4.GetObject().SetName("point 4")
    with operation(prim_operations):
        Box = prim_operations.MakeBoxTwoPnt(pnt1, pnt2).GetObject()
        BoxBool = prim_operations.MakeBoxTwoPnt(pnt3, pnt4).GetObject()
    root = doc.Main().Root()
    viewer = TPrsStd_AISViewer().New(root, display.Context_handle).GetObject()
    with operation(bool_operations):
        fff = bool_operations.MakeBoolean(Box.GetHandle(), BoxBool.GetHandle(), 1).GetObject()
    dt = TPrsStd_DriverTable()
    dt.Get()
    dt.InitStandardDrivers()
    prs1 = register_presentation(Box)
    prs2 = register_presentation(BoxBool)
    prs3 = register_presentation(fff)
    prs1.SetTransparency(0.8)
    prs2.SetTransparency(0.8)
    prs1.SetColor(12)
    prs2.SetColor(200)
    prs3.SetColor(100)
    def update():
        prs1.Update()
        prs2.Update()
        prs3.Update()
        viewer.Update()
        display.FitAll()
parameters.add_callback(update)
    for i in range(-66, -11):
        parameters.depth_a = i
    for i in range(-80, 0):
        parameters.height_a = i
    for i in range(-44, 0):
        parameters.width_a = i
add_menu('GEOM')
add_function_to_menu('GEOM', example_parametric_box)
start_display()
 
        
Wed, 06/10/2009 - 18:10
Hello Jelle
There is no "automatic" way to update a TPrsStd_AISPresentation on change of the underlying geometry.You will propably need to access somehow the updated object's TPrsStd_AISPresentation and call its Update() method.In case you need to update all the objects (GEOM_Object) in the DataFramework then you can itterate the tree using TDF_ChildIterator and search for all AISPresentation classes and call their update method.
In order to automate the presentation updating you can always wrap the GEOM_Solver methods and update manually your objects.
Greets
Fotis Sioutis