Ejemplo n.º 1
0
/*!
  Set the node compatibility mask for node type \a nodetype.  The mask
  specifies for which file formats the node is supported.

  \COIN_FUNCTION_EXTENSION

  \sa getCompatibilityMode()
  \since Coin 2.0
*/
void
SoNode::setCompatibilityTypes(const SoType & nodetype, const uint32_t bitmask)
{
  assert(compatibility_dict);
  assert(nodetype.isDerivedFrom(SoNode::getClassTypeId()));
  compatibility_dict->put(nodetype.getKey(), bitmask);
}
Ejemplo n.º 2
0
// Documented in superclass.
void
SoWinExaminerViewer::setCamera(SoCamera * newCamera)
{
  // This method overridden from parent class to toggle the camera
  // type selection button pixmap and string of the zoom/dolly
  // thumbwheel.

  inherited::setCamera(newCamera);

  if (! newCamera)
    return;

  SoType camtype = newCamera->getTypeId();
  SbBool orthogonal =
    camtype.isDerivedFrom(SoOrthographicCamera::getClassTypeId());

  const char * oldLabel = this->getRightWheelString();
  if (oldLabel) {
    if (orthogonal) {
      if (strcmp("Dolly",oldLabel) == 0)
        this->setRightWheelString("Zoom");
    }
    else if (strcmp("Zoom",oldLabel) == 0)
      this->setRightWheelString("Dolly");
  }
  SoWinBitmapButton * wbtn = PRIVATE(this)->camerabutton;
  // If viewer was made without decorations, button will not have been
  // made yet.
  if (wbtn) { wbtn->setBitmap(orthogonal ? 1 : 0); }
}
Ejemplo n.º 3
0
void
SoUnknownEngine::copyContents(const SoFieldContainer *fromFC,
			      SbBool copyConnections)
//
////////////////////////////////////////////////////////////////////////
{
    // Make sure the copy has the correct class name
    const SoUnknownEngine *fromUnk = (const SoUnknownEngine *) fromFC;
    setClassName(fromUnk->className);

    // For each input in the original engine, create a new input and add
    // it to the new engine

    // NOTE: We can't use SoEngine::copyContents() to copy the field
    // data, since that uses SoFieldData::overlay(), which assumes the
    // fields have the same offsets in both engines. Instead, we just
    // copy the field values ourselves.

    const SoFieldData *fromData = fromUnk->getFieldData();
    SoFieldData  *toData	= (SoFieldData *) getFieldData();
    int i;
    for (i = 0; i < fromData->getNumFields(); i++) {

	SoField      *fromField	= fromData->getField(fromUnk, i);
        const SbName fieldName	= fromData->getFieldName(i);
        SoType       fieldType	= fromField->getTypeId();
        SoField      *toField	= (SoField *) (fieldType.createInstance());

        toField->enableNotify(FALSE);
        toField->setContainer(this);
        toField->setDefault(TRUE);
        toField->enableNotify(TRUE);

        toData->addField(this, fieldName.getString(), toField);

	toField->setContainer(this);
	toField->copyFrom(*fromField);
	toField->setIgnored(fromField->isIgnored());
	toField->setDefault(fromField->isDefault());
	toField->fixCopy(copyConnections);
	if (fromField->isConnected() && copyConnections)
	    toField->copyConnection(fromField);
    }

    // Copy the outputs
    SoEngineOutputData *toOutData = (SoEngineOutputData *) getOutputData();

    SoEngineOutputList outList;
    fromUnk->getOutputs(outList);

    for(i = 0; i < outList.getLength(); i++) {
        SoEngineOutput *newOut = new SoEngineOutput;
        const SoType outType = outList[i]->getConnectionType();
	SbName outName;
        getOutputName( outList[i], outName );
	toOutData->addOutput(this, outName.getString(), newOut, outType);
	newOut->setContainer(this);
    }
}
Ejemplo n.º 4
0
void
SoUnknownNode::createFromIsA(SoMFString *isA)
//
////////////////////////////////////////////////////////////////////////
{
    for (int i = 0; i < isA->getNum(); i++) {
	SoType t = SoType::fromName((*isA)[i]);

	if (t.canCreateInstance() &&
	    t.isDerivedFrom(SoNode::getClassTypeId())) {

	    SoNode *alternateRep = (SoNode *)t.createInstance();
	    alternateRep->ref();
#ifdef DEBUG
	    if (alternateRep == NULL) {
		SoDebugError::post("SoUnknownNode::createFromIsA",
				   "SoType.createInstance returned "
				   "NULL (type %s)",
				   t.getName().getString());
		return;
	    }
#endif
	    // Copy over all fields that are shared:
	    int num = instanceFieldData->getNumFields();
	    for (int j=0; j<num; j++) {
		const SbName &fieldName = instanceFieldData->getFieldName(j);
		SoField *f = instanceFieldData->getField(this, j);
		// Don't copy over fields with default values:
		if (f->isDefault()) continue;
		
		SoField *nf = alternateRep->getField(fieldName);
		if (nf != NULL && nf->getTypeId() == f->getTypeId()) {
		    nf->copyFrom(*f);
		    if (f->isConnectedFromField()) {
			SoField *cf;
			f->getConnectedField(cf);
			nf->connectFrom(cf);
		    } else if (f->isConnectedFromEngine()) {
			SoEngineOutput *eo;
			f->getConnectedEngine(eo);
			nf->connectFrom(eo);
		    }
		}
	    }
	    // And if alternateRep is a group, copy over hidden
	    // children:
	    if (alternateRep->isOfType(SoGroup::getClassTypeId())) {
		SoGroup *g = (SoGroup *)alternateRep;
		for (int kid = 0; kid < hiddenChildren.getLength();
		     kid++) {
		    g->addChild(hiddenChildren[kid]);
		}
	    }
	    addChild(alternateRep);
	    return;
	}
    }
}
Ejemplo n.º 5
0
/*!
  Get the node compatibility mask for node type \a nodetype.  The
  return value will be a bit mask of SoNode::NodeType flags,
  containing one or several flags.

  \COIN_FUNCTION_EXTENSION

  \since Coin 2.0
*/
uint32_t
SoNode::getCompatibilityTypes(const SoType & nodetype)
{
  assert(compatibility_dict);
  assert(nodetype.isDerivedFrom(SoNode::getClassTypeId()));

  uint32_t tmp;
  if (compatibility_dict->get(nodetype.getKey(), tmp)) { return tmp; }
  return SoNode::EXTENSION;
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::setCameraType(SoType type)
{
    if(!getSoRenderManager()->getCamera()->isOfType(SoPerspectiveCamera::getClassTypeId()) &&
            !getSoRenderManager()->getCamera()->isOfType(SoOrthographicCamera::getClassTypeId())) {
        Base::Console().Warning("Quarter::setCameraType",
                                "Only SoPerspectiveCamera and SoOrthographicCamera is supported.");
        return;
    }


    SoType perspectivetype = SoPerspectiveCamera::getClassTypeId();
    SbBool oldisperspective = getSoRenderManager()->getCamera()->getTypeId().isDerivedFrom(perspectivetype);
    SbBool newisperspective = type.isDerivedFrom(perspectivetype);

    if((oldisperspective && newisperspective) ||
            (!oldisperspective && !newisperspective)) // Same old, same old..
        return;


    SoCamera* currentcam = getSoRenderManager()->getCamera();
    SoCamera* newcamera = (SoCamera*)type.createInstance();

    // Transfer and convert values from one camera type to the other.
    if(newisperspective) {
        convertOrtho2Perspective((SoOrthographicCamera*)currentcam,
                                 (SoPerspectiveCamera*)newcamera);
    }
    else {
        convertPerspective2Ortho((SoPerspectiveCamera*)currentcam,
                                 (SoOrthographicCamera*)newcamera);
    }

    getSoRenderManager()->setCamera(newcamera);
    getSoEventManager()->setCamera(newcamera);

    //if the superscene has a camera we need to replace it too
    SoSeparator* superscene = (SoSeparator*) getSoRenderManager()->getSceneGraph();
    SoSearchAction sa;
    sa.setInterest(SoSearchAction::FIRST);
    sa.setType(SoCamera::getClassTypeId());
    sa.apply(superscene);

    if(sa.getPath()) {
        SoNode* node = sa.getPath()->getTail();
        SoGroup* parent = (SoGroup*) sa.getPath()->getNodeFromTail(1);

        if(node && node->isOfType(SoCamera::getClassTypeId())) {
            parent->replaceChild(node, newcamera);
        }
    }
};
Ejemplo n.º 7
0
void
SoActionMethodList::addMethod(SoType nodeType, SoActionMethod method)
//
////////////////////////////////////////////////////////////////////////
{
#ifdef DEBUG
    // Make sure nodeType is a kind of node!
    if (! nodeType.isDerivedFrom(SoNode::getClassTypeId()))
	SoDebugError::post("SoAction::addMethod", "%s is not a node type",
			   nodeType.getName().getString());
#endif /* DEBUG */

    numValidTypes = 0;
    (*this)[SoNode::getActionMethodIndex(nodeType)] = method;
}
void SIM::Coin3D::Quarter::SoQTQuarterAdaptor::saveHomePosition(void)
{
    SoType t = getSoRenderManager()->getCamera()->getTypeId();
    assert(t.isDerivedFrom(SoNode::getClassTypeId()));
    assert(t.canCreateInstance());

    if(m_storedcamera) {
        m_storedcamera->unref();
    }

    m_storedcamera = (SoNode*)t.createInstance();
    m_storedcamera->ref();

    m_storedcamera->copyFieldValues(getSoRenderManager()->getCamera());
}
Ejemplo n.º 9
0
SoActionMethod
SoActionMethodList::parentMethod(SoType t)
//
////////////////////////////////////////////////////////////////////////
{
    SoActionMethod m;
    SoType parent = t;

    // Look through parents until non-NULL method is found
    do {
	parent = parent.getParent();
	m = (*this)[SoNode::getActionMethodIndex(parent)];
    } while (m == NULL);

    return m;
}
Ejemplo n.º 10
0
/*!
  This method makes a new class's instantiation method override
  the instantiation method of an existing class.

  The new type should be a C++ subclass of the original class type, but
  this won't be checked though.

  If \c NULL is passed as the second argument, the type will be
  considered uninstantiable -- it does not revert the configuration to
  the default setting as one might think.

  Here's a \e complete code examples which shows how to fully override
  a built-in Coin node class, so that a) your application-specific
  extension class gets instantiated instead of the built-in class upon
  scenegraph import, and b) it gets written out properly upon export:

  \code
  #include <Inventor/SoDB.h>
  #include <Inventor/actions/SoWriteAction.h>
  #include <Inventor/errors/SoDebugError.h>
  #include <Inventor/nodes/SoSeparator.h>
  #include <Inventor/nodes/SoWWWInline.h>

  ////// MyWWWInline ////////////////////////////////////////////////////

  class MyWWWInline : public SoWWWInline {
    SO_NODE_HEADER(MyWWWInline);

  public:
    static void initClass(void);
    MyWWWInline(void);

  protected:
    virtual ~MyWWWInline();
    virtual SbBool readInstance(SoInput * in, unsigned short flags);
    virtual const char * getFileFormatName(void) const;
  };

  SO_NODE_SOURCE(MyWWWInline);

  MyWWWInline::MyWWWInline(void)
  {
    SO_NODE_CONSTRUCTOR(MyWWWInline);

    // Fool the library to believe this is an internal class, so it gets
    // written out in the same manner as the built-in classes, instead
    // of as en extension class. There are slight differences, which you
    // want to avoid when overriding a class like we do with MyWWWInline
    // vs SoWWWInline here.
    this->isBuiltIn = TRUE;
  }

  MyWWWInline::~MyWWWInline()
  {
  }

  void
  MyWWWInline::initClass(void)
  {
    SO_NODE_INIT_CLASS(MyWWWInline, SoWWWInline, "SoWWWInline");

    // Override instantiation method, so we get MyWWWInline instead of
    // SoWWWInline instances upon scenegraph import.
    (void)SoType::overrideType(SoWWWInline::getClassTypeId(),
                               MyWWWInline::createInstance);
  }

  // Override SoBase::getFileFormatName() to make node get written as
  // "WWWInline" instead of "MyWWWInline".
  const char *
  MyWWWInline::getFileFormatName(void) const
  {
    return "WWWInline";
  }

  SbBool
  MyWWWInline::readInstance(SoInput * in, unsigned short flags)
  {
    SoDebugError::postInfo("MyWWWInline::readInstance", "hepp");
    return SoWWWInline::readInstance(in, flags);
  }

  ////// main() /////////////////////////////////////////////////////////

  int
  main(int argc, char ** argv)
  {
    SoDB::init();
    MyWWWInline::initClass();

    const char * ivscene =
      "#Inventor V2.1 ascii\n\n"
      "Separator {"
      "  WWWInline { }"
      "}";

    SoInput in;
    in.setBuffer((void *)ivscene, strlen(ivscene));
    SoSeparator * root = SoDB::readAll(&in);
    root->ref();

    SoOutput out;
    SoWriteAction wa(&out);
    wa.apply(root);
    root->unref();

    return 0;
  }
  \endcode
*/
const SoType
SoType::overrideType(const SoType originalType,
                     const instantiationMethod method)
{
  (*SoType::typedatalist)[(int)originalType.getKey()]->method = method;
  return originalType;
}
Ejemplo n.º 11
0
/*!
  This method appends all the class types derived from \a type to \a list,
  and returns the number of types added to the list.  Internal types are not
  included in the list, nor are they counted.

  \a type itself is also added to the list, as a type is seen as a derivation
  of its own type.

  NB: do not write code which depends in any way on the order of the
  elements returned in \a list.

  Here is a small, stand-alone example which shows how this method can
  be used for introspection, listing all subclasses of the SoBase
  superclass:

  \code
  #include <stdio.h>
  #include <Inventor/SoDB.h>
  #include <Inventor/lists/SoTypeList.h>

  static void
  list_subtypes(SoType t, unsigned int indent = 0)
  {
    SoTypeList tl;
    SoType::getAllDerivedFrom(t, tl);

    for (unsigned int i=0; i < indent; i++) { printf("  "); }
    printf("%s\n", t.getName().getString());

    indent++;
    for (int j=0; j < tl.getLength(); j++) {
      if (tl[j].getParent() == t) { // only interested in direct descendents
        list_subtypes(tl[j], indent);
      }
    }
  }

  int
  main(void)
  {
    SoDB::init();

    list_subtypes(SoType::fromName("SoBase"));

    return 0;
  }
  \endcode
*/
int
SoType::getAllDerivedFrom(const SoType type, SoTypeList & list)
{
  assert(type != SoType::badType() && "argument is badType()");

  int counter = 0;
  int n = SoType::typedatalist->getLength();
  for (int i = 0; i < n; i++) {
    if ((*SoType::typedatalist)[i]) {
      SoType chktype = (*SoType::typedatalist)[i]->type;
      if (!chktype.isInternal() && chktype.isDerivedFrom(type)) {
        list.append(chktype);
        counter++;
      }
    }
  }
  return counter;
}
Ejemplo n.º 12
0
int
main(void)
{
  SoDB::init();
  SoNodeKit::init();
  SoInteraction::init();

  SoTypeList tl;
  const unsigned int n = SoType::getAllDerivedFrom(SoNode::getClassTypeId(), tl);
  for (unsigned int i=0; i < n; i++) {
    (void)fprintf(stdout, "%s", tl[i].getName().getString());

    SoFieldContainer * fc = (SoFieldContainer *)
      (tl[i].canCreateInstance() ? tl[i].createInstance() : NULL);

    if (fc == NULL) {
      (void)fprintf(stdout, "  (abstract)\n");
      continue;
    }

    (void)fprintf(stdout, "\n");

    SoFieldList fl;
    const unsigned int nrf = fc->getAllFields(fl);
    for (unsigned int j=0; j < nrf; j++) {
      SoField * f = fl[j];
      SoType ftype = f->getTypeId();
      SbName fname;
      f->getContainer()->getFieldName(f, fname);
      (void)fprintf(stdout, "  %s (%s)\n",
                    fname.getString(),
                    ftype.getName().getString());

      if (ftype.isDerivedFrom(SoSFEnum::getClassTypeId())) {
        list_enums((SoSFEnum *)f);
      }
      else if (ftype.isDerivedFrom(SoMFEnum::getClassTypeId())) {
        list_enums((SoMFEnum *)f);
      }
    }
  }

  return 0;
}
Ejemplo n.º 13
0
/*!
  Creates an instance of a suitable SoForeignFileKit subtype.
  Returns NULL on failure or a kit with refcount of 1 on success.
*/
static SoForeignFileKit *create_foreignfilekit(const char *filename, SbBool exhaust)
{
  assert(SoForeignFileKitP::fileexts != NULL);

  const char * extptr = strrchr(filename, '.');
  if (extptr) {
    extptr++;
    SbName ext(SbString(extptr).lower());
    SoType handler = SoType::badType();
    if (SoForeignFileKitP::fileexts->get(ext.getString(), handler)) {
      SoForeignFileKit * foreignfile = (SoForeignFileKit *)handler.createInstance();
      foreignfile->ref();
      if (foreignfile->canReadFile(filename)) {
        return foreignfile;
      }
      else {
        foreignfile->unref();
      }
    }
    else {
      // We try to synthesize a classname from the extension (e.g. SoFBXFileKit),
      // and load it using the SoType autoloader feature.
      SbString filekitname;
      filekitname.sprintf("So%sFileKit", SbString(ext.getString()).upper().getString());
      SoType filekittype = SoType::fromName(SbName(filekitname));
      if (!filekittype.isBad()) return create_foreignfilekit(filename, exhaust);

      // FIXME: Some filekits supports more than one file format/extension (e.g. FBX).
      // We need a way of mapping extensions to library, or a way of loading
      // each external kit and testing for support.
      // FIXME: Temporary hack: Load SoFBXFileKit
      filekitname = "SoFBXFileKit";
      filekittype = SoType::fromName(SbName(filekitname));
      if (!filekittype.isBad()) return create_foreignfilekit(filename, exhaust);
    }
  }
  if (exhaust) {
    // FIXME: Implement
    // SoForeignFileKitP::fileexts->apply()
  }
  return NULL;
}
SoCallbackAction::Response
SoIntersectionDetectionAction::PImpl::dragger(SoCallbackAction * action, const SoNode *)
{
  if ( !this->draggersenabled ) // dragger setting overrides setting for manipulators
    return SoCallbackAction::PRUNE;
#ifdef HAVE_MANIPULATORS
  if ( !this->manipsenabled ) {
    const SoPath * path = action->getCurPath();
    SoNode * tail = path->getTail();
    SoType type = tail->getTypeId();
    if ( type.isDerivedFrom(SoTransformManip::getClassTypeId()) ||
         type.isDerivedFrom(SoClipPlaneManip::getClassTypeId()) ||
         type.isDerivedFrom(SoDirectionalLightManip::getClassTypeId()) ||
         type.isDerivedFrom(SoPointLightManip::getClassTypeId()) ||
         type.isDerivedFrom(SoSpotLightManip::getClassTypeId()) )
      return SoCallbackAction::PRUNE;
  }
#endif // HAVE_MANIPULATORS
  return SoCallbackAction::CONTINUE;
}
Ejemplo n.º 15
0
SbBool
SoType::isDerivedFrom(const SoType parent) const
{
  assert(!this->isBad());

  if (parent.isBad()) {
#if COIN_DEBUG
    SoDebugError::postWarning("SoType::isDerivedFrom",
                              "can't compare type '%s' against an invalid type",
                              this->getName().getString());
#endif // COIN_DEBUG
    return FALSE;
  }

  SoType type = *this;
  do {
#if COIN_DEBUG && 0 // debug
    SoDebugError::postInfo("SoType::isDerivedFrom",
                           "this: '%s' parent: '%s'",
                           type.getName().getString(),
                           parent.getName().getString());
#endif // debug
    if (type == parent) return TRUE;
    type = (*SoType::typedatalist)[(int)type.getKey()]->parent;
  } while (!type.isBad());

  return FALSE;
}
Ejemplo n.º 16
0
void
SoEnabledElementsList::enable(SoType elementType, int stackIndex)
//
////////////////////////////////////////////////////////////////////////
{
    SoType prev = elements[stackIndex];

    // If not enabled before or if enabled before but we are now
    // enabling a more-specific subclass, add the element.
    if (prev.isBad() || 
	(elementType != prev && elementType.isDerivedFrom(prev))) {
	elements.set(stackIndex, elementType);

	// Increment global counter to indicate that lists have changed
	counter++;
    }

#ifdef DEBUG
    // If we aren't enabling a more general super-class (and therefore
    // don't need to do anything), error:
    else if (! prev.isDerivedFrom(elementType)) {
	const char *eltName = elementType.getName().getString();
	SoDebugError::post("SoAction::enableElement",
			   "Cannot enable element %s because element %s "
			   "is already enabled",
			   eltName, prev.getName().getString());
    }
#endif
}
Ejemplo n.º 17
0
/*!
  Upgrade \a base, usually created using SoUpgrader::tryCreateNode(),
  to the latest version of the same node.
*/
SoBase *
SoUpgrader::createUpgrade(const SoBase * base)
{
  soupgrader_init_classes();

  SoType type = base->getTypeId();

  if (type == SoPackedColorV20::getClassTypeId()) {
    SoPackedColorV20 * pp = (SoPackedColorV20*) base;
    return (SoBase*) pp->createUpgrade();
  }
  else if (type == SoShapeHintsV10::getClassTypeId()) {
    SoShapeHintsV10 * pp = (SoShapeHintsV10*) base;
    return (SoBase*) pp->createUpgrade();
  }
  else {
    SoDebugError::post("SoUpgrader::createUpgrade",
                       "No upgrade functionality available for %s",
                       type.getName().getString());
  }
  return NULL;
}
Ejemplo n.º 18
0
const SoTypeList &
SoEnabledElementsList::getElements() const
//
////////////////////////////////////////////////////////////////////////
{
    // Cast const away
    SoEnabledElementsList *This = (SoEnabledElementsList *)this;

    // We only need to merge with our parent's list if some element
    // has been enabled since the last time we merged.
    if (setUpCounter != counter) {

	// We may enable new things here which could increment the 
	// enabled elements counter. But all of these elements were already
	// enabled once by the parent class. So we'll store the counter 
	// now and restore it after this loop...
	This->setUpCounter = counter;

	SoEnabledElementsList *parentList = parent;
	while (parentList) {
	    int		i;
	    SoType	t;

	    for (i = 0; i < parentList->elements.getLength(); i++) {
		t = parentList->elements[i];
		if (! t.isBad())
			This->enable(t, i);
	    }

	    parentList = parentList->parent;
	}

	// restore the counter...
	counter = This->setUpCounter;
    }

    return elements;
}
SbBool
SoIntersectionDetectionAction::isTypeEnabled(SoType type, SbBool checkgroups) const
{
  if ( PRIVATE(this)->prunetypes->find(type) != -1 ) return FALSE;
  if ( checkgroups ) {
    // is type a dragger?
#ifdef HAVE_DRAGGERS
    if ( !PRIVATE(this)->draggersenabled &&
         type.isDerivedFrom(SoDragger::getClassTypeId()) ) return FALSE;
#endif // HAVE_DRAGGERS
#ifdef HAVE_MANIPULATORS
    // is type a manip?
    if ( !PRIVATE(this)->manipsenabled ) {
      if ( type.isDerivedFrom(SoTransformManip::getClassTypeId()) ||
           type.isDerivedFrom(SoClipPlaneManip::getClassTypeId()) ||
           type.isDerivedFrom(SoDirectionalLightManip::getClassTypeId()) ||
           type.isDerivedFrom(SoPointLightManip::getClassTypeId()) ||
           type.isDerivedFrom(SoSpotLightManip::getClassTypeId()) ) return FALSE;
    }
#endif // HAVE_MANIPULATORS
  }
  return TRUE;
}
Ejemplo n.º 20
0
const SoType
SoType::createType(const SoType parent, const SbName name,
                   const instantiationMethod method,
                   const uint16_t data)
{
#if COIN_DEBUG
  // We don't use SoType::fromName() to test if a type with this name
  // already exists to avoid loading extension nodes in this context.
  // You should be able to "override" dynamically loadable nodes in program
  // code.
  // FIXME: We ought to factor out and expose this functionality - testing
  // if a class type is already loaded and registered - in the public API.
  // 20040831 larsa  (ref could-have-been-used-to-fix-upgrader-slowness-bug)
  int16_t discard;
  if (type_dict->get(name.getString(), discard)) {
    SoDebugError::post("SoType::createType",
                       "a type with name ``%s'' already created",
                       name.getString());
    return SoType::fromName(name.getString());
  }
#endif // COIN_DEBUG

#if COIN_DEBUG && 0 // debug
  SoDebugError::postInfo("SoType::createType", "%s", name.getString());
#endif // debug

  SoType newType;
  newType.index = SoType::typedatalist->getLength();
  SoTypeData * typeData = new SoTypeData(name, newType, TRUE, data, parent, method);
  SoType::typedatalist->append(typeData);

  // add to dictionary for fast lookup
  type_dict->put(name.getString(), newType.getKey());

  return newType;
}
Ejemplo n.º 21
0
/*!
  Try creating a node of name \a name with Inventor version \a ivversion.

  Returns NULL if no such node exists.
*/
SoBase *
SoUpgrader::tryCreateNode(const SbName & name, const float ivversion)
{
  if ((ivversion == 1.0f) || (ivversion == 2.0f)) {
    soupgrader_init_classes();

    SbString s(name.getString());
    s += (ivversion == 1.0f) ? "V10" : "V20";

    if (soupgrader_exists(s.getString())) {
      SoType type = SoType::fromName(SbName(s.getString()));
      if (type.canCreateInstance()) {
        SoBase * b = (SoBase*) type.createInstance();
        if (SoInputP::debug()) {
          SoDebugError::postInfo("SoUpgrader::tryCreateNode",
                                 "name=='%s', ivversion==%f => SoBase==%p",
                                 name.getString(), ivversion, b);
        }
        return b;
      }
    }
  }
  return NULL;
}
Ejemplo n.º 22
0
SbBool
SoGate::readInstance(SoInput *in, unsigned short flags)
//
////////////////////////////////////////////////////////////////////////
{
    SbName typeName;
    if (!in->read(typeName, TRUE) ||
		typeName != "type" || !typeField.read(in, "type")) {

	SoReadError::post(in, "SoGate is missing type field");
	return FALSE;
    }

    SoType inputType = SoType::fromName(typeField.getValue());
    if (! inputType.isDerivedFrom(SoMField::getClassTypeId())) {
	SoReadError::post(in, "\"%s\" is not a type of MField",
			  typeField.getValue().getString());
	return FALSE;
    }
    
    setup(inputType);

    return SoEngine::readInstance(in, flags);
}
Ejemplo n.º 23
0
SoGate::SoGate(SoType inputType)
//
////////////////////////////////////////////////////////////////////////
{
    SO_ENGINE_CONSTRUCTOR(SoGate);
    SO_ENGINE_ADD_INPUT(enable, (0));
    SO_ENGINE_ADD_INPUT(trigger, ());

    myInputData = new SoFieldData(inputData);
    myOutputData = new SoEngineOutputData(outputData);
    input = NULL;

    setup(inputType);
    typeField.setValue(inputType.getName());

    isBuiltIn = TRUE;
}
Ejemplo n.º 24
0
/*!
  Registers a concrete SoForeignFileKit subtype to be a handler for files with the given extension.
  One class can be a handler for multiple filename extensions.
  
  FIXME: \e identify is not implemented
 */
SbBool
SoForeignFileKit::registerFileExtension(SoType handler, SbName extension, SoForeignFileIdentifyFunc * COIN_UNUSED_ARG(identify))
{
  assert(SoForeignFileKitP::fileexts != NULL);
  assert(handler.canCreateInstance());

  if (extension.getString()[0] == '.') {
#if COIN_DEBUG
    SoDebugError::post("SoForeignFileKit::registerFileExtension",
                       "Do not include the extension separator '.' "
                       "when registering file extension.");
#endif // COIN_DEBUG
  }

  if (SoForeignFileKitP::fileexts->put(extension.getString(), handler)) {
    return TRUE;
  }
  return FALSE;
}
SbBool GestureNavigationStyle::processSoEvent(const SoEvent * const ev)
{
    // Events when in "ready-to-seek" mode are ignored, except those
    // which influence the seek mode itself -- these are handled further
    // up the inheritance hierarchy.
    if (this->isSeekMode()) { return inherited::processSoEvent(ev); }
    // Switch off viewing mode (Bug #0000911)
    if (!this->isSeekMode()&& !this->isAnimating() && this->isViewing() )
        this->setViewing(false); // by default disable viewing mode to render the scene
    //setViewing() is never used in this style, so the previous if is very unlikely to be hit.

    const SoType type(ev->getTypeId());
    //define some shortcuts...
    bool evIsButton = type.isDerivedFrom(SoMouseButtonEvent::getClassTypeId());
    bool evIsKeyboard = type.isDerivedFrom(SoKeyboardEvent::getClassTypeId());
    bool evIsLoc2 = type.isDerivedFrom(SoLocation2Event::getClassTypeId());//mouse movement
    bool evIsLoc3 = type.isDerivedFrom(SoMotion3Event::getClassTypeId());//spaceball/joystick movement
    bool evIsGesture = type.isDerivedFrom(SoGestureEvent::getClassTypeId());//touchscreen gesture

    const SbVec2f prevnormalized = this->lastmouseposition;
    const SbVec2s pos(ev->getPosition());//not valid for gestures
    const SbVec2f posn = this->normalizePixelPos(pos);
    //pos: local coordinates of event, in pixels
    //posn: normalized local coordinates of event ((0,0) = lower left corner, (1,1) = upper right corner)
    float ratio = viewer->getSoRenderManager()->getViewportRegion().getViewportAspectRatio();

    if (evIsButton || evIsLoc2){
        this->lastmouseposition = posn;
    }

    const ViewerMode curmode = this->currentmode;
    //ViewerMode newmode = curmode;

    //make a unified mouse+modifiers state value (combo)
    enum {
        BUTTON1DOWN = 1 << 0,
        BUTTON2DOWN = 1 << 1,
        BUTTON3DOWN = 1 << 2,
        CTRLDOWN =    1 << 3,
        SHIFTDOWN =   1 << 4,
        ALTDOWN =     1 << 5,
        MASKBUTTONS = BUTTON1DOWN | BUTTON2DOWN | BUTTON3DOWN,
        MASKMODIFIERS = CTRLDOWN | SHIFTDOWN | ALTDOWN
    };
    unsigned int comboBefore = //before = state before this event
        (this->button1down ? BUTTON1DOWN : 0) |
        (this->button2down ? BUTTON2DOWN : 0) |
        (this->button3down ? BUTTON3DOWN : 0) |
        (this->ctrldown ? CTRLDOWN : 0) |
        (this->shiftdown ? SHIFTDOWN : 0) |
        (this->altdown ? ALTDOWN : 0);

    //test for complex clicks
    int cntMBBefore = (comboBefore & BUTTON1DOWN ? 1 : 0 ) //cntMBBefore = how many buttons were down when this event arrived?
                  +(comboBefore & BUTTON2DOWN ? 1 : 0 )
                  +(comboBefore & BUTTON3DOWN ? 1 : 0 );
    if (cntMBBefore>=2) this->thisClickIsComplex = true;
    if (cntMBBefore==0) {//a good chance to reset some click-related stuff
        this->thisClickIsComplex = false;
        this->mousedownConsumedCount = 0;//shouldn't be necessary, just a fail-safe.
    }

    // Mismatches in state of the modifier keys happens if the user
    // presses or releases them outside the viewer window.
    this->ctrldown = ev->wasCtrlDown();
    this->shiftdown = ev->wasShiftDown();
    this->altdown = ev->wasAltDown();
    //before this block, mouse button states in NavigationStyle::buttonXdown reflected those before current event arrived.
    //track mouse button states
    if (evIsButton) {
        const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
        const int button = event->getButton();
        const SbBool press //the button was pressed (if false -> released)
                = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
        switch (button) {
        case SoMouseButtonEvent::BUTTON1:
            this->button1down = press;
            break;
        case SoMouseButtonEvent::BUTTON2:
            this->button2down = press;
            break;
        case SoMouseButtonEvent::BUTTON3:
            this->button3down = press;
            break;
        //whatever else, we don't track
        }
    }
    //after this block, the new states of the buttons are already in.

    unsigned int comboAfter = //after = state after this event (current, essentially)
        (this->button1down ? BUTTON1DOWN : 0) |
        (this->button2down ? BUTTON2DOWN : 0) |
        (this->button3down ? BUTTON3DOWN : 0) |
        (this->ctrldown ? CTRLDOWN : 0) |
        (this->shiftdown ? SHIFTDOWN : 0) |
        (this->altdown ? ALTDOWN : 0);

    //test for complex clicks (again)
    int cntMBAfter = (comboAfter & BUTTON1DOWN ? 1 : 0 ) //cntMBAfter = how many buttons were down when this event arrived?
                  +(comboAfter & BUTTON2DOWN ? 1 : 0 )
                  +(comboAfter & BUTTON3DOWN ? 1 : 0 );
    if (cntMBAfter>=2) this->thisClickIsComplex = true;
    //if (cntMBAfter==0) this->thisClickIsComplex = false;//don't reset the flag now, we need to know that this mouseUp was an end of a click that was complex. The flag will reset by the before-check in the next event.

    //test for move detection
    if (evIsLoc2 || evIsButton){
        this->mouseMoveThresholdBroken |= this->testMoveThreshold(pos);
    }

    //track gestures
    if (evIsGesture) {
        const SoGestureEvent* gesture = static_cast<const SoGestureEvent*>(ev);
        switch(gesture->state) {
        case SoGestureEvent::SbGSStart:
            //assert(!inGesture);//start of another gesture before the first finished? Happens all the time for Pan gesture... No idea why!  --DeepSOIC
            inGesture = true;
        break;
        case SoGestureEvent::SbGSUpdate:
            assert(inGesture);//gesture update without start?
            inGesture = true;
        break;
        case SoGestureEvent::SbGSEnd:
            assert(inGesture);//gesture ended without starting?
            inGesture = false;
        break;
        case SoGestureEvent::SbGsCanceled:
            assert(inGesture);//gesture canceled without starting?
            inGesture=false;
        break;
        default:
            assert(0);//shouldn't happen
            inGesture = false;
        }
    }
    if (evIsButton) {
        if(inGesture){
            inGesture = false;//reset the flag when mouse clicks are received, to ensure enabling mouse navigation back.
            setViewingMode(NavigationStyle::SELECTION);//exit navigation asap, to proceed with regular processing of the click
        }
    }

    bool suppressLMBDrag = false;
    if(viewer->isEditing()){
        //in edit mode, disable lmb dragging (spinning). Holding Alt enables it.
        suppressLMBDrag = !(comboAfter & ALTDOWN);
    }

    //----------all this were preparations. Now comes the event handling! ----------

    SbBool processed = FALSE;//a return value for the  BlahblahblahNavigationStyle::processSoEvent
    bool propagated = false;//an internal flag indicating that the event has been already passed to inherited, to suppress the automatic doing of this at the end.
    //goto finalize = return processed. Might be important to do something before done (none now).

    // give the nodes in the foreground root the chance to handle events (e.g color bar)
    if (!viewer->isEditing()) {
        processed = handleEventInForeground(ev);
    }
    if (processed)
        goto finalize;

    // Mode-independent keyboard handling
    if (evIsKeyboard) {
        const SoKeyboardEvent * const event = (const SoKeyboardEvent *) ev;
        const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
        switch (event->getKey()) {
        case SoKeyboardEvent::H:
            processed = TRUE;
            if(!press){
                SbBool ret = NavigationStyle::lookAtPoint(event->getPosition());
                if(!ret){
                    Base::Console().Warning(
                        "No object under cursor! Can't set new center of rotation.\n");
                }
            }
            break;
        default:
            break;
        }
    }
    if (processed)
        goto finalize;

    //mode-independent spaceball/joystick handling
    if (evIsLoc3) {
        const SoMotion3Event * const event = static_cast<const SoMotion3Event * const>(ev);
        if (event)
            this->processMotionEvent(event);
        processed = TRUE;
    }
    if (processed)
        goto finalize;

    //all mode-dependent stuff is within this switch.
    switch(curmode){
    case NavigationStyle::IDLE:
    case NavigationStyle::SELECTION:
    case NavigationStyle::INTERACT: {
        //idle and interaction

        //keyboard
        if (evIsKeyboard) {
            const SoKeyboardEvent * const event = (const SoKeyboardEvent *) ev;
            const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;

            switch(event->getKey()){
            case SoKeyboardEvent::S:
            case SoKeyboardEvent::HOME:
            case SoKeyboardEvent::LEFT_ARROW:
            case SoKeyboardEvent::UP_ARROW:
            case SoKeyboardEvent::RIGHT_ARROW:
            case SoKeyboardEvent::DOWN_ARROW:
                processed = inherited::processSoEvent(ev);
                propagated = true;
                break;
            case SoKeyboardEvent::PAGE_UP:
                if(press){
                    doZoom(viewer->getSoRenderManager()->getCamera(), TRUE, posn);
                }
                processed = TRUE;
                break;
            case SoKeyboardEvent::PAGE_DOWN:
                if(press){
                    doZoom(viewer->getSoRenderManager()->getCamera(), FALSE, posn);
                }
                processed = TRUE;
                break;
            default:
                break;
            }//switch key
        }
        if (processed)
            goto finalize;


        // Mouse Button / Spaceball Button handling
        if (evIsButton) {
            const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
            const int button = event->getButton();
            const SbBool press //the button was pressed (if false -> released)
                    = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
            switch(button){
            case SoMouseButtonEvent::BUTTON1:
            case SoMouseButtonEvent::BUTTON2:
                if(press){
                    if(this->thisClickIsComplex && this->mouseMoveThresholdBroken){
                        //this should prevent re-attempts to enter navigation when doing more clicks after a move.
                    } else {
                        //on LMB-down or RMB-down, we don't know yet if we should propagate it or process it. Save the event to be refired later, when it becomes clear.
                        //reset/start move detection machine
                        this->mousedownPos = pos;
                        this->mouseMoveThresholdBroken = false;
                        pan(viewer->getSoRenderManager()->getCamera());//set up panningplane
                        int &cnt = this->mousedownConsumedCount;
                        this->mousedownConsumedEvent[cnt] = *event;//hopefully, a shallow copy is enough. There are no pointers stored in events, apparently. Will loose a subclass, though.
                        cnt++;
                        assert(cnt<=2);
                        if(cnt>static_cast<int>(sizeof(mousedownConsumedEvent))){
                            cnt=sizeof(mousedownConsumedEvent);//we are in trouble
                        }
                        processed = true;//just consume this event, and wait for the move threshold to be broken to start dragging/panning
                    }
                } else {//release
                    if (button == SoMouseButtonEvent::BUTTON2 && !this->thisClickIsComplex) {
                        if (!viewer->isEditing() && this->isPopupMenuEnabled()) {
                            processed=true;
                            this->openPopupMenu(event->getPosition());
                        }
                    }
                    if(! processed) {
                        //re-synthesize all previously-consumed mouseDowns, if any. They might have been re-synthesized already when threshold was broken.
                        for( int i=0;   i < this->mousedownConsumedCount;   i++ ){
                            inherited::processSoEvent(& (this->mousedownConsumedEvent[i]));//simulate the previously-comsumed mousedown.
                        }
                        this->mousedownConsumedCount = 0;
                        processed = inherited::processSoEvent(ev);//explicitly, just for clarity that we are sending a full click sequence.
                        propagated = true;
                    }
                }
            break;
            case SoMouseButtonEvent::BUTTON3://press the wheel
                processed = TRUE;
                if(press){
                    SbBool ret = NavigationStyle::lookAtPoint(event->getPosition());
                    if(!ret){
                        Base::Console().Warning(
                            "No object under cursor! Can't set new center of rotation.\n");
                    }
                }
                break;
            case SoMouseButtonEvent::BUTTON4: //(wheel?)
                doZoom(viewer->getSoRenderManager()->getCamera(), TRUE, posn);
                processed = TRUE;
                break;
            case SoMouseButtonEvent::BUTTON5: //(wheel?)
                doZoom(viewer->getSoRenderManager()->getCamera(), FALSE, posn);
                processed = TRUE;
                break;
            }
        }

        //mouse moves - test for move threshold breaking
        if (evIsLoc2) {
            if (this->mouseMoveThresholdBroken && (this->button1down || this->button2down) && mousedownConsumedCount > 0) {
                //mousemovethreshold has JUST been broken

                //test if we should enter navigation
                if ((this->button1down && !suppressLMBDrag) || this->button2down) {
                    //yes, we are entering navigation.
                    //throw away consumed mousedowns.
                    this->mousedownConsumedCount = 0;

                    setViewingMode(this->button1down ? NavigationStyle::DRAGGING : NavigationStyle::PANNING);
                    processed = true;
                } else {
                    //no, we are not entering navigation.
                    //re-synthesize all previously-consumed mouseDowns, if any, and propagate this mousemove.
                    for( int i=0;   i < this->mousedownConsumedCount;   i++ ){
                        inherited::processSoEvent(& (this->mousedownConsumedEvent[i]));//simulate the previously-comsumed mousedown.
                    }
                    this->mousedownConsumedCount = 0;
                    processed = inherited::processSoEvent(ev);//explicitly, just for clarity that we are sending a full click sequence.
                    propagated = true;
                }
            }
            if (mousedownConsumedCount  > 0)
                processed = true;//if we are still deciding if it's a drag or not, consume mouseMoves.
        }

        //gesture start
        if (evIsGesture && /*!this->button1down &&*/ !this->button2down){//ignore gestures when mouse buttons are down. Button1down check was disabled because of wrong state after doubleclick on sketcher constraint to edit datum
            const SoGestureEvent* gesture = static_cast<const SoGestureEvent*>(ev);
            if (gesture->state == SoGestureEvent::SbGSStart
                    || gesture->state == SoGestureEvent::SbGSUpdate) {//even if we didn't get a start, assume the first update is a start (sort-of fail-safe).
                if (type.isDerivedFrom(SoGesturePanEvent::getClassTypeId())) {
                    pan(viewer->getSoRenderManager()->getCamera());//set up panning plane
                    setViewingMode(NavigationStyle::PANNING);
                    processed = true;
                } else if (type.isDerivedFrom(SoGesturePinchEvent::getClassTypeId())) {
                    pan(viewer->getSoRenderManager()->getCamera());//set up panning plane
                    setViewingMode(NavigationStyle::DRAGGING);
                    processed = true;
                } //all other gestures - ignore!
            }
        }

        //loc2 (mousemove) - ignore.

    } break;//end of idle and interaction
    case NavigationStyle::DRAGGING:
    case NavigationStyle::ZOOMING:
    case NavigationStyle::PANNING:{
        //actual navigation

        //no keyboard.

        // Mouse Button / Spaceball Button handling
        if (evIsButton) {
            const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
            const int button = event->getButton();
            //const SbBool press //the button was pressed (if false -> released)
            //        = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
            switch(button){
            case SoMouseButtonEvent::BUTTON1:
            case SoMouseButtonEvent::BUTTON2:
                if(comboAfter & BUTTON1DOWN || comboAfter & BUTTON2DOWN) {
                    //don't leave navigation till all buttons have been released
                    setViewingMode((comboAfter & BUTTON1DOWN) ? NavigationStyle::DRAGGING : NavigationStyle::PANNING);
                    processed = true;
                } else { //all buttons are released
                    //end of dragging/panning/whatever
                    setViewingMode(NavigationStyle::SELECTION);
                    processed = true;
                } //else of if (some bottons down)
            break;
            } //switch(button)
        } //if(evIsButton)

        //the essence part 1!
        //mouse movement into camera motion. Suppress if in gesture. Ignore until threshold is surpassed.
        if (evIsLoc2 && ! this->inGesture && this->mouseMoveThresholdBroken) {
            //const SoLocation2Event * const event = (const SoLocation2Event *) ev;
            if (curmode == NavigationStyle::ZOOMING) {//doesn't happen
                this->zoomByCursor(posn, prevnormalized);
                processed = TRUE;
            } else if (curmode == NavigationStyle::PANNING) {
                panCamera(viewer->getSoRenderManager()->getCamera(), ratio, this->panningplane, posn, prevnormalized);
                processed = TRUE;
            } else if (curmode == NavigationStyle::DRAGGING) {
                if (comboAfter & BUTTON1DOWN && comboAfter & BUTTON2DOWN) {
                    //two mouse buttons down - tilting!
                    NavigationStyle::doRotate(viewer->getSoRenderManager()->getCamera(),
                                              (posn - prevnormalized)[0]*(-2),
                                              SbVec2f(0.5,0.5));
                    processed = TRUE;
                } else {//one mouse button - normal spinning
                    //this will also handle the single-finger drag (there's no gesture used, pseudomouse is enough)
                    //this->addToLog(event->getPosition(), event->getTime());
                    this->spin_simplified(viewer->getSoRenderManager()->getCamera(),
                                          posn, prevnormalized);
                    processed = TRUE;
                }
            }
        }

        //the essence part 2!
        //gesture into camera motion
        if (evIsGesture){
            const SoGestureEvent* gesture = static_cast<const SoGestureEvent*>(ev);
            assert(gesture);
            if (gesture->state == SoGestureEvent::SbGSEnd) {
                setViewingMode(NavigationStyle::SELECTION);
                processed=true;
            } else if (gesture->state == SoGestureEvent::SbGSUpdate){
                if(type.isDerivedFrom(SoGesturePinchEvent::getClassTypeId())){
                    const SoGesturePinchEvent* const event = static_cast<const SoGesturePinchEvent* const>(ev);
                    if (this->zoomAtCursor){
                        //this is just dealing with the pan part of pinch gesture. Taking care of zooming to pos is done in doZoom.
                        SbVec2f panDist = this->normalizePixelPos(event->deltaCenter.getValue());
                        NavigationStyle::panCamera(viewer->getSoRenderManager()->getCamera(), ratio, this->panningplane, panDist, SbVec2f(0,0));
                    }
                    NavigationStyle::doZoom(viewer->getSoRenderManager()->getCamera(),-logf(event->deltaZoom),this->normalizePixelPos(event->curCenter));
                    if (event->deltaAngle != 0)
                        NavigationStyle::doRotate(viewer->getSoRenderManager()->getCamera(),event->deltaAngle,this->normalizePixelPos(event->curCenter));
                    processed = true;
                }
                if(type.isDerivedFrom(SoGesturePanEvent::getClassTypeId())){
                    const SoGesturePanEvent* const event = static_cast<const SoGesturePanEvent* const>(ev);
                        //this is just dealing with the pan part of pinch gesture. Taking care of zooming to pos is done in doZoom.
                    SbVec2f panDist = this->normalizePixelPos(event->deltaOffset);
                    NavigationStyle::panCamera(viewer->getSoRenderManager()->getCamera(), ratio, this->panningplane, panDist, SbVec2f(0,0));
                    processed = true;
                }
            } else {
                //shouldn't happen. Gestures are not expected to start in the middle of navigation.
                //we'll consume it, without reacting.
                processed=true;
                //This does, unfortunately, happen on regular basis for pan gesture on Windows8.1+Qt4.8
            }
        }

    } break;//end of actual navigation
    case NavigationStyle::SEEK_WAIT_MODE:{
        if (evIsButton) {
            const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
            const int button = event->getButton();
            const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
            if (button == SoMouseButtonEvent::BUTTON1 && press) {
                this->seekToPoint(pos); // implicitly calls interactiveCountInc()
                this->setViewingMode(NavigationStyle::SEEK_MODE);
                processed = true;
            }
        }
    } ; //not end of SEEK_WAIT_MODE. Fall through by design!!!
    case NavigationStyle::SPINNING:
    case NavigationStyle::SEEK_MODE: {
        //animation modes
        if (!processed) {
            if (evIsButton || evIsGesture || evIsKeyboard || evIsLoc3)
                setViewingMode(NavigationStyle::SELECTION);
        }
    } break; //end of animation modes
    case NavigationStyle::BOXZOOM:
    default:
        //all the rest - will be pass on to inherited, later.
        break;
    }

    if (! processed && ! propagated) {
        processed = inherited::processSoEvent(ev);
        propagated = true;
    }

    //-----------------------end of event handling---------------------
finalize:
    return processed;
}
Ejemplo n.º 26
0
SbBool CADNavigationStyle::processSoEvent(const SoEvent * const ev)
{
#if 0
    // Events when in "ready-to-seek" mode are ignored, except those
    // which influence the seek mode itself -- these are handled further
    // up the inheritance hierarchy.
    if (this->isSeekMode()) { return inherited::processSoEvent(ev); }
#else
    if (!this->isSeekMode() && this->isViewing())
        this->setViewing(false); // by default disable viewing mode to render the scene
#endif

    const SoType type(ev->getTypeId());

    const SbViewportRegion & vp = viewer->getViewportRegion();
    const SbVec2s size(vp.getViewportSizePixels());
    const SbVec2f prevnormalized = this->lastmouseposition;
    const SbVec2s pos(ev->getPosition());
    const SbVec2f posn((float) pos[0] / (float) SoQtMax((int)(size[0] - 1), 1),
                       (float) pos[1] / (float) SoQtMax((int)(size[1] - 1), 1));

    this->lastmouseposition = posn;

    // Set to TRUE if any event processing happened. Note that it is not
    // necessary to restrict ourselves to only do one "action" for an
    // event, we only need this flag to see if any processing happened
    // at all.
    SbBool processed = FALSE;

    const ViewerMode curmode = this->currentmode;
    ViewerMode newmode = curmode;

    // Mismatches in state of the modifier keys happens if the user
    // presses or releases them outside the viewer window.
    if (this->ctrldown != ev->wasCtrlDown()) {
        this->ctrldown = ev->wasCtrlDown();
    }
    if (this->shiftdown != ev->wasShiftDown()) {
        this->shiftdown = ev->wasShiftDown();
    }
    if (this->altdown != ev->wasAltDown()) {
        this->altdown = ev->wasAltDown();
    }

    // give the nodes in the foreground root the chance to handle events (e.g color bar)
    if (!processed && !viewer->isEditing()) {
        processed = handleEventInForeground(ev);
        if (processed)
            return TRUE;
    }

    // Keyboard handling
    if (type.isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
        const SoKeyboardEvent * const event = (const SoKeyboardEvent *) ev;
        const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
        switch (event->getKey()) {
        case SoKeyboardEvent::LEFT_CONTROL:
        case SoKeyboardEvent::RIGHT_CONTROL:
            this->ctrldown = press;
            break;
        case SoKeyboardEvent::LEFT_SHIFT:
        case SoKeyboardEvent::RIGHT_SHIFT:
            this->shiftdown = press;
            break;
        case SoKeyboardEvent::LEFT_ALT:
        case SoKeyboardEvent::RIGHT_ALT:
            this->altdown = press;
            break;
        case SoKeyboardEvent::H:
            processed = TRUE;
            viewer->saveHomePosition();
            break;
        case SoKeyboardEvent::S:
        case SoKeyboardEvent::HOME:
        case SoKeyboardEvent::LEFT_ARROW:
        case SoKeyboardEvent::UP_ARROW:
        case SoKeyboardEvent::RIGHT_ARROW:
        case SoKeyboardEvent::DOWN_ARROW:
            if (!this->isViewing())
                this->setViewing(true);
            break;
        default:
            break;
        }
    }

    // Mouse Button / Spaceball Button handling
    if (type.isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
        const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
        const int button = event->getButton();
        const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;

        // SoDebugError::postInfo("processSoEvent", "button = %d", button);
        switch (button) {
        case SoMouseButtonEvent::BUTTON1:
            this->lockrecenter = TRUE;
            this->button1down = press;
#if 0 // disable to avoid interferences where this key combination is used, too
            if (press && ev->wasShiftDown() &&
                (this->currentmode != NavigationStyle::SELECTION)) {
                this->centerTime = ev->getTime();
                float ratio = vp.getViewportAspectRatio();
                SbViewVolume vv = viewer->getCamera()->getViewVolume(ratio);
                this->panningplane = vv.getPlane(viewer->getCamera()->focalDistance.getValue());
                this->lockrecenter = FALSE;
            }
            else if (!press && ev->wasShiftDown() &&
                (this->currentmode != NavigationStyle::SELECTION)) {
                SbTime tmp = (ev->getTime() - this->centerTime);
                float dci = (float)QApplication::doubleClickInterval()/1000.0f;
                // is it just a left click?
                if (tmp.getValue() < dci && !this->lockrecenter) {
                    if (!this->moveToPoint(pos)) {
                        panToCenter(panningplane, posn);
                        this->interactiveCountDec();
                    }
                    processed = TRUE;
                }
            }
            else
#endif
            if (press && (this->currentmode == NavigationStyle::SEEK_WAIT_MODE)) {
                newmode = NavigationStyle::SEEK_MODE;
                this->seekToPoint(pos); // implicitly calls interactiveCountInc()
                processed = TRUE;
            }
            //else if (press && (this->currentmode == NavigationStyle::IDLE)) {
            //    this->setViewing(true);
            //    processed = TRUE;
            //}
            else if (press && (this->currentmode == NavigationStyle::PANNING ||
                               this->currentmode == NavigationStyle::ZOOMING)) {
                newmode = NavigationStyle::DRAGGING;
                this->centerTime = ev->getTime();
                processed = TRUE;
            }
            else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) {
                SbTime tmp = (ev->getTime() - this->centerTime);
                float dci = (float)QApplication::doubleClickInterval()/1000.0f;
                if (tmp.getValue() < dci) {
                    newmode = NavigationStyle::ZOOMING;
                }
                processed = TRUE;
            }
            else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) {
                this->setViewing(false);
                processed = TRUE;
            }
            else if (viewer->isEditing() && (this->currentmode == NavigationStyle::SPINNING)) {
                processed = TRUE;
            }
            break;
        case SoMouseButtonEvent::BUTTON2:
            // If we are in edit mode then simply ignore the RMB events
            // to pass the event to the base class.
            this->lockrecenter = TRUE;
            if (!viewer->isEditing()) {
                // If we are in zoom or pan mode ignore RMB events otherwise
                // the canvas doesn't get any release events 
                if (this->currentmode != NavigationStyle::ZOOMING && 
                    this->currentmode != NavigationStyle::PANNING &&
                    this->currentmode != NavigationStyle::DRAGGING) {
                    if (this->isPopupMenuEnabled()) {
                        if (!press) { // release right mouse button
                            this->openPopupMenu(event->getPosition());
                        }
                    }
                }
            }
            // Alternative way of rotating & zooming
            if (press && (this->currentmode == NavigationStyle::PANNING ||
                          this->currentmode == NavigationStyle::ZOOMING)) {
                newmode = NavigationStyle::DRAGGING;
                this->centerTime = ev->getTime();
                processed = TRUE;
            }
            else if (!press && (this->currentmode == NavigationStyle::DRAGGING)) {
                SbTime tmp = (ev->getTime() - this->centerTime);
                float dci = (float)QApplication::doubleClickInterval()/1000.0f;
                if (tmp.getValue() < dci) {
                    newmode = NavigationStyle::ZOOMING;
                }
                processed = TRUE;
            }
            this->button2down = press;
            break;
        case SoMouseButtonEvent::BUTTON3:
            if (press) {
                this->centerTime = ev->getTime();
                float ratio = vp.getViewportAspectRatio();
                SbViewVolume vv = viewer->getCamera()->getViewVolume(ratio);
                this->panningplane = vv.getPlane(viewer->getCamera()->focalDistance.getValue());
                this->lockrecenter = FALSE;
            }
            else {
                SbTime tmp = (ev->getTime() - this->centerTime);
                float dci = (float)QApplication::doubleClickInterval()/1000.0f;
                // is it just a middle click?
                if (tmp.getValue() < dci && !this->lockrecenter) {
                    if (!this->lookAtPoint(pos)) {
                        panToCenter(panningplane, posn);
                        this->interactiveCountDec();
                    }
                    processed = TRUE;
                }
            }
            this->button3down = press;
            break;
        case SoMouseButtonEvent::BUTTON4:
            doZoom(viewer->getCamera(), TRUE, posn);
            processed = TRUE;
            break;
        case SoMouseButtonEvent::BUTTON5:
            doZoom(viewer->getCamera(), FALSE, posn);
            processed = TRUE;
            break;
        default:
            break;
        }
    }

    // Mouse Movement handling
    if (type.isDerivedFrom(SoLocation2Event::getClassTypeId())) {
        this->lockrecenter = TRUE;
        const SoLocation2Event * const event = (const SoLocation2Event *) ev;
        if (this->currentmode == NavigationStyle::ZOOMING) {
            this->zoomByCursor(posn, prevnormalized);
            processed = TRUE;
        }
        else if (this->currentmode == NavigationStyle::PANNING) {
            float ratio = vp.getViewportAspectRatio();
            panCamera(viewer->getCamera(), ratio, this->panningplane, posn, prevnormalized);
            processed = TRUE;
        }
        else if (this->currentmode == NavigationStyle::DRAGGING) {
            this->addToLog(event->getPosition(), event->getTime());
            this->spin(posn);
            processed = TRUE;
        }
    }

    // Spaceball & Joystick handling
    if (type.isDerivedFrom(SoMotion3Event::getClassTypeId())) {
        const SoMotion3Event * const event = static_cast<const SoMotion3Event * const>(ev);
        if (event)
            this->processMotionEvent(event);
        processed = TRUE;
    }

    enum {
        BUTTON1DOWN = 1 << 0,
        BUTTON3DOWN = 1 << 1,
        CTRLDOWN =    1 << 2,
        SHIFTDOWN =   1 << 3,
        BUTTON2DOWN = 1 << 4
    };
    unsigned int combo =
        (this->button1down ? BUTTON1DOWN : 0) |
        (this->button2down ? BUTTON2DOWN : 0) |
        (this->button3down ? BUTTON3DOWN : 0) |
        (this->ctrldown ? CTRLDOWN : 0) |
        (this->shiftdown ? SHIFTDOWN : 0);

    switch (combo) {
    case 0:
        if (curmode == NavigationStyle::SPINNING) { break; }
        newmode = NavigationStyle::IDLE;
        // The left mouse button has been released right now but
        // we want to avoid that the event is procesed elsewhere
        if (this->lockButton1) {
            this->lockButton1 = FALSE;
            processed = TRUE;
        }

        //if (curmode == NavigationStyle::DRAGGING) {
        //    if (doSpin())
        //        newmode = NavigationStyle::SPINNING;
        //}
        break;
    case BUTTON1DOWN:
        // make sure not to change the selection when stopping spinning
        if (curmode == NavigationStyle::SPINNING || this->lockButton1)
            newmode = NavigationStyle::IDLE;
        else
            newmode = NavigationStyle::SELECTION;
        break;
    case BUTTON3DOWN:
        if (curmode == NavigationStyle::SPINNING) { break; }
        else if (newmode == NavigationStyle::ZOOMING) { break; }
        newmode = NavigationStyle::PANNING;

        if (curmode == NavigationStyle::DRAGGING) {
            if (doSpin()) {
                newmode = NavigationStyle::SPINNING;
                break;
            }
        }
        break;
    case CTRLDOWN|BUTTON2DOWN:
        newmode = NavigationStyle::PANNING;
        break;
    case SHIFTDOWN|BUTTON2DOWN:
        newmode = NavigationStyle::DRAGGING;
        break;
    case CTRLDOWN|SHIFTDOWN|BUTTON2DOWN:
        newmode = NavigationStyle::ZOOMING;
        break;
    //case CTRLDOWN:
    //case CTRLDOWN|BUTTON1DOWN:
    //case CTRLDOWN|SHIFTDOWN:
    //case CTRLDOWN|SHIFTDOWN|BUTTON1DOWN:
    //    newmode = NavigationStyle::SELECTION;
    //    break;
    //case BUTTON1DOWN|BUTTON3DOWN:
    //case CTRLDOWN|BUTTON3DOWN:
    //    newmode = NavigationStyle::ZOOMING;
    //    break;

        // There are many cases we don't handle that just falls through to
        // the default case, like SHIFTDOWN, CTRLDOWN, CTRLDOWN|SHIFTDOWN,
        // SHIFTDOWN|BUTTON3DOWN, SHIFTDOWN|CTRLDOWN|BUTTON3DOWN, etc.
        // This is a feature, not a bug. :-)
        //
        // mortene.

    default:
        // The default will make a spin stop and otherwise not do
        // anything.
        //if ((curmode != NavigationStyle::SEEK_WAIT_MODE) &&
        //    (curmode != NavigationStyle::SEEK_MODE)) {
        //    newmode = NavigationStyle::IDLE;
        //}
        break;
    }

    if (newmode != curmode) {
        this->setViewingMode(newmode);
    }

    // If for dragging the buttons 1 and 3 are pressed
    // but then button 3 is relaesed we shouldn't switch
    // into selection mode.
    if (this->button1down && this->button3down)
        this->lockButton1 = TRUE;

    // If not handled in this class, pass on upwards in the inheritance
    // hierarchy.
    if (/*(curmode == NavigationStyle::SELECTION || viewer->isEditing()) && */!processed)
        processed = inherited::processSoEvent(ev);
    else
        return TRUE;

    return processed;
}
Ejemplo n.º 27
0
/*!
  \COININTERNAL
*/
int
SoNode::getActionMethodIndex(const SoType type)
{
  return type.getData();
}
Ejemplo n.º 28
0
SbBool TouchpadNavigationStyle::processSoEvent(const SoEvent * const ev)
{
    // Events when in "ready-to-seek" mode are ignored, except those
    // which influence the seek mode itself -- these are handled further
    // up the inheritance hierarchy.
    if (this->isSeekMode()) { return inherited::processSoEvent(ev); }
    // Switch off viewing mode (Bug #0000911)
    if (!this->isSeekMode() && !this->isAnimating() && this->isViewing())
        this->setViewing(false); // by default disable viewing mode to render the scene

    const SoType type(ev->getTypeId());

    const SbViewportRegion & vp = viewer->getSoRenderManager()->getViewportRegion();
    const SbVec2s size(vp.getViewportSizePixels());
    const SbVec2f prevnormalized = this->lastmouseposition;
    const SbVec2s pos(ev->getPosition());
    const SbVec2f posn((float) pos[0] / (float) std::max((int)(size[0] - 1), 1),
                       (float) pos[1] / (float) std::max((int)(size[1] - 1), 1));

    this->lastmouseposition = posn;

    // Set to TRUE if any event processing happened. Note that it is not
    // necessary to restrict ourselves to only do one "action" for an
    // event, we only need this flag to see if any processing happened
    // at all.
    SbBool processed = FALSE;

    const ViewerMode curmode = this->currentmode;
    ViewerMode newmode = curmode;

    // Mismatches in state of the modifier keys happens if the user
    // presses or releases them outside the viewer window.
    if (this->ctrldown != ev->wasCtrlDown()) {
        this->ctrldown = ev->wasCtrlDown();
    }
    if (this->shiftdown != ev->wasShiftDown()) {
        this->shiftdown = ev->wasShiftDown();
    }
    if (this->altdown != ev->wasAltDown()) {
        this->altdown = ev->wasAltDown();
    }

    // give the nodes in the foreground root the chance to handle events (e.g color bar)
    if (!processed && !viewer->isEditing()) {
        processed = handleEventInForeground(ev);
        if (processed)
            return TRUE;
    }

    // Keyboard handling
    if (type.isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
        const SoKeyboardEvent * const event = (const SoKeyboardEvent *) ev;
        const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;
        switch (event->getKey()) {
        case SoKeyboardEvent::LEFT_CONTROL:
        case SoKeyboardEvent::RIGHT_CONTROL:
            this->ctrldown = press;
            break;
        case SoKeyboardEvent::LEFT_SHIFT:
        case SoKeyboardEvent::RIGHT_SHIFT:
            this->shiftdown = press;
            break;
        case SoKeyboardEvent::LEFT_ALT:
        case SoKeyboardEvent::RIGHT_ALT:
            this->altdown = press;
            break;
        case SoKeyboardEvent::H:
            processed = TRUE;
            viewer->saveHomePosition();
            break;
        case SoKeyboardEvent::S:
        case SoKeyboardEvent::HOME:
        case SoKeyboardEvent::LEFT_ARROW:
        case SoKeyboardEvent::UP_ARROW:
        case SoKeyboardEvent::RIGHT_ARROW:
        case SoKeyboardEvent::DOWN_ARROW:
            if (!this->isViewing())
                this->setViewing(true);
            break;
        case SoKeyboardEvent::PAGE_UP:
            doZoom(viewer->getSoRenderManager()->getCamera(), TRUE, posn);
            processed = TRUE;
            break;
        case SoKeyboardEvent::PAGE_DOWN:
            doZoom(viewer->getSoRenderManager()->getCamera(), FALSE, posn);
            processed = TRUE;
            break;
        default:
            break;
        }
    }

    // Mouse Button / Spaceball Button handling
    if (type.isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
        const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
        const int button = event->getButton();
        const SbBool press = event->getState() == SoButtonEvent::DOWN ? TRUE : FALSE;

        // SoDebugError::postInfo("processSoEvent", "button = %d", button);
        switch (button) {
        case SoMouseButtonEvent::BUTTON1:
            this->lockrecenter = TRUE;
            this->button1down = press;
            if (press && (this->currentmode == NavigationStyle::SEEK_WAIT_MODE)) {
                newmode = NavigationStyle::SEEK_MODE;
                this->seekToPoint(pos); // implicitly calls interactiveCountInc()
                processed = TRUE;
            }
            else if (press && (this->currentmode == NavigationStyle::PANNING ||
                               this->currentmode == NavigationStyle::ZOOMING)) {
                newmode = NavigationStyle::DRAGGING;
                saveCursorPosition(ev);
                this->centerTime = ev->getTime();
                processed = TRUE;
            }
            else if (viewer->isEditing() && (this->currentmode == NavigationStyle::SPINNING)) {
                processed = TRUE;
            }
            break;
        case SoMouseButtonEvent::BUTTON2:
            // If we are in edit mode then simply ignore the RMB events
            // to pass the event to the base class.
            this->lockrecenter = TRUE;
            if (!viewer->isEditing()) {
                // If we are in zoom or pan mode ignore RMB events otherwise
                // the canvas doesn't get any release events 
                if (this->currentmode != NavigationStyle::ZOOMING && 
                    this->currentmode != NavigationStyle::PANNING &&
                    this->currentmode != NavigationStyle::DRAGGING) {
                    if (this->isPopupMenuEnabled()) {
                        if (!press) { // release right mouse button
                            this->openPopupMenu(event->getPosition());
                        }
                    }
                }
            }
            // Alternative way of rotating & zooming
            if (press && (this->currentmode == NavigationStyle::PANNING ||
                          this->currentmode == NavigationStyle::ZOOMING)) {
                newmode = NavigationStyle::DRAGGING;
                saveCursorPosition(ev);
                this->centerTime = ev->getTime();
                processed = TRUE;
            }
            this->button2down = press;
            break;
        case SoMouseButtonEvent::BUTTON4:
            doZoom(viewer->getSoRenderManager()->getCamera(), TRUE, posn);
            processed = TRUE;
            break;
        case SoMouseButtonEvent::BUTTON5:
            doZoom(viewer->getSoRenderManager()->getCamera(), FALSE, posn);
            processed = TRUE;
            break;
        default:
            break;
        }
    }

    // Mouse Movement handling
    if (type.isDerivedFrom(SoLocation2Event::getClassTypeId())) {
        this->lockrecenter = TRUE;
        const SoLocation2Event * const event = (const SoLocation2Event *) ev;
        if (this->currentmode == NavigationStyle::ZOOMING) {
            this->zoomByCursor(posn, prevnormalized);
            processed = TRUE;
        }
        else if (this->currentmode == NavigationStyle::PANNING) {
            float ratio = vp.getViewportAspectRatio();
            panCamera(viewer->getSoRenderManager()->getCamera(), ratio, this->panningplane, posn, prevnormalized);
            processed = TRUE;
        }
        else if (this->currentmode == NavigationStyle::DRAGGING) {
            this->addToLog(event->getPosition(), event->getTime());
            this->spin(posn);
            moveCursorPosition();
            processed = TRUE;
        }
    }

    // Spaceball & Joystick handling
    if (type.isDerivedFrom(SoMotion3Event::getClassTypeId())) {
        const SoMotion3Event * const event = static_cast<const SoMotion3Event * const>(ev);
        if (event)
            this->processMotionEvent(event);
        processed = TRUE;
    }

    enum {
        BUTTON1DOWN = 1 << 0,
        BUTTON2DOWN = 1 << 1,
        CTRLDOWN =    1 << 2,
        SHIFTDOWN =   1 << 3,
        ALTDOWN =     1 << 4
    };
    unsigned int combo =
        (this->button1down ? BUTTON1DOWN : 0) |
        (this->button2down ? BUTTON2DOWN : 0) |
        (this->ctrldown ? CTRLDOWN : 0) |
        (this->shiftdown ? SHIFTDOWN : 0) |
        (this->altdown ? ALTDOWN : 0);

    switch (combo) {
    case 0:
        if (curmode == NavigationStyle::SPINNING) { break; }
        newmode = NavigationStyle::IDLE;
        break;
    case BUTTON1DOWN:
        // make sure not to change the selection when stopping spinning
        if (curmode == NavigationStyle::SPINNING)
            newmode = NavigationStyle::IDLE;
        else
            newmode = NavigationStyle::SELECTION;
        break;
    case CTRLDOWN:
        newmode = NavigationStyle::IDLE;
        break;
    case SHIFTDOWN:
        newmode = NavigationStyle::PANNING;
        break;
    case ALTDOWN:
        if (newmode != NavigationStyle::DRAGGING) {
            saveCursorPosition(ev);
        }
        newmode = NavigationStyle::DRAGGING;
        break;
    case CTRLDOWN|SHIFTDOWN:
    case CTRLDOWN|SHIFTDOWN|BUTTON1DOWN:
        newmode = NavigationStyle::ZOOMING;
        break;
    default:
        break;
    }

    if (newmode != curmode) {
        this->setViewingMode(newmode);
    }

    // If not handled in this class, pass on upwards in the inheritance
    // hierarchy.
    if (!processed)
        processed = inherited::processSoEvent(ev);
    else
        return TRUE;

    return processed;
}
Ejemplo n.º 29
0
TSeparatorKit* ComponentHeliostatField::CreateField()
{
	//Define heliostat tracker for the field
	QVector< TTrackerFactory* > trackersFactoryList = m_pPluginManager->GetTrackerFactories();
	if( trackersFactoryList.size() == 0 )
	{
        QMessageBox::warning( 0, QString( "Campo Heliostatos" ),
        		QString( "No se ha encontrado plugins de tipo tracker." ) );
		return 0;
	}

	QVector< QString > trackerNames;
	for( int i = 0; i < trackersFactoryList.size(); i++ )
		trackerNames<< trackersFactoryList[i]->TTrackerName();

	int selectedTracker = trackerNames.indexOf( QLatin1String( "Heliostat_tracker" ) );
	if( selectedTracker < 0 )
	{
        QMessageBox::warning( 0, QString( "Campo Heliostatos" ),
        		QString( "No se ha encontrado el plugin de tipo 'Heliostat_tracker' " ) );
		return 0;
	}

	TTrackerFactory* heliostatTrackerFactory = trackersFactoryList[ selectedTracker ];


	HeliostatFieldWizard wizard;
	if( !wizard.exec() )
	{
		QMessageBox::information( 0, QString( "Campo Heliostatos" ),
				QString( "The field has not been created." ) );
		return 0;
	}

	//Aiming point
	Point3D aimingPoint = wizard.GetHeliostatsAimingPoint();

	//Read heliostat component

	//TSeparatorKit::initClass();

	TSeparatorKit* heliostatComponentNode = OpenHeliostatComponent( wizard.GetHeliostatComponentFile() );
	if( !heliostatComponentNode )
	{
		QMessageBox::information( 0, QString( "Campo Heliostatos" ),
				QString( "Error al leer el componente para los heliostatos." ) );
		return 0;
	}


	QFile coordinatesFile( wizard.GetCoordinatesFile() );
	if( !coordinatesFile.open( QIODevice::ReadOnly ) )
	{
		QMessageBox::information( 0, QString( "Campo Heliostatos" ),
				QString( "Error al leer el archivo de coordenadas de los heliostatos." ) );
		return 0;
	}


	QTextStream coordIn( &coordinatesFile );


	std::vector< Point3D > hCenterList;
	while( !coordIn.atEnd() )
	{
		QString inLine = coordIn.readLine();
		QStringList heliostat = inLine.split(QRegExp("[\\t,;]"), QString::SkipEmptyParts);
		if( heliostat.count() >=3 )
			hCenterList.push_back( Point3D( heliostat[0].toDouble(),
					heliostat[1].toDouble(),
					heliostat[2].toDouble() ) );
	}


	SoType separatorType = SoType::fromName( SbName ( "TSeparatorKit" ) );

	/*TSeparatorKit* rootSeparator = static_cast< TSeparatorKit* > ( separatorType.createInstance() );
	//TSeparatorKit* rootSeparator = new TSeparatorKit;
	rootSeparator->setName( "CampoHeliostatos" );
	rootSeparator->ref();

	SoNodeKitListPart* rootPartList = static_cast< SoNodeKitListPart* >( rootSeparator->getPart( "childList", true ) );
	if( !rootPartList ) return 0;
	*/


	TSeparatorKit* heliostatsNodeSeparator = static_cast< TSeparatorKit* > ( separatorType.createInstance() );
	//TSeparatorKit* heliostatsNodeSeparator = new TSeparatorKit;
	//rootPartList->addChild(heliostatsNodeSeparator);
	heliostatsNodeSeparator->setName( "Heliostatos" );
	heliostatsNodeSeparator->ref();



	CreateHeliostatZones( hCenterList, heliostatsNodeSeparator, heliostatTrackerFactory, aimingPoint, heliostatComponentNode, 1 );

	return heliostatsNodeSeparator;

}
Ejemplo n.º 30
0
void ComponentHeliostatField::CreateHeliostatZones( std::vector< Point3D >  heliostatCenterList, TSeparatorKit* parentNode,
		TTrackerFactory* heliostatTrackerFactory,
		Point3D aimingPoint,
		TSeparatorKit* heliostatComponentNode,
		int eje )
{

	SoType separatorType = SoType::fromName( SbName ( "TSeparatorKit" ) );

	SoNodeKitListPart* heliostatsNodePartList = static_cast< SoNodeKitListPart* >( parentNode->getPart( "childList", true ) );
	if( !heliostatsNodePartList ) return;

	int nHeliostatCenters = ( int ) heliostatCenterList.size();
	if( nHeliostatCenters < 8 )
	{

		for( int nHeliostat = 0; nHeliostat < nHeliostatCenters; nHeliostat++ )
		{

			//TSeparatorKit* heliostatSeparator = new TSeparatorKit;
			TSeparatorKit* heliostatSeparator = static_cast< TSeparatorKit* > ( separatorType.createInstance() );
			heliostatsNodePartList->addChild(heliostatSeparator);
			QString heliostatName = QString( QLatin1String( "Heliostat%1" ) ).arg( QString::number( nHeliostat ) );
			heliostatSeparator->setName( heliostatName.toStdString().c_str() );
			SoTransform* nodeTransform = dynamic_cast< SoTransform* >( heliostatSeparator->getPart( "transform", true ) );
			nodeTransform->translation.setValue( heliostatCenterList[nHeliostat].x,
					heliostatCenterList[nHeliostat].y,
					heliostatCenterList[nHeliostat].z );

			SoNodeKitListPart*  heliostatPartList = static_cast< SoNodeKitListPart* >( heliostatSeparator->getPart( "childList", true ) );
			if( !heliostatPartList ) return;

			//TSeparatorKit* heliostatTrackerNode= new TSeparatorKit;
			TSeparatorKit* heliostatTrackerNode = static_cast< TSeparatorKit* > ( separatorType.createInstance() );
			heliostatPartList->addChild( heliostatTrackerNode );
			heliostatTrackerNode->setName( "HeliostatTrackerNode" );
			SoNodeKitListPart*  heliostaTrackerNodetPartList = static_cast< SoNodeKitListPart* >( heliostatTrackerNode->getPart( "childList", true ) );
			if( !heliostaTrackerNodetPartList ) return;

			TTracker* tracker = heliostatTrackerFactory->CreateTTracker();
			heliostatTrackerNode->setPart( "tracker", tracker );
			SoSFVec3f* aimingPointField = dynamic_cast< SoSFVec3f* > ( tracker->getField ( "aimingPoint" ) );
			if( aimingPointField )	aimingPointField->setValue( SbVec3f( aimingPoint.x, aimingPoint.y, aimingPoint.z ) );

			if( heliostatComponentNode )	heliostaTrackerNodetPartList->addChild( heliostatComponentNode );

		}
	}
	else
	{
		//TSeparatorKit* heliostatSeparator1 = new TSeparatorKit;
		TSeparatorKit* heliostatSeparator1 = static_cast< TSeparatorKit* > ( separatorType.createInstance() );
		heliostatsNodePartList->addChild(heliostatSeparator1);
		QString heliostatName1 = QString( QLatin1String( "DivisionPor%1_1" ) ).arg( ( eje == 3 )? QString( 'Z' ): QString( 'X' ) );
		heliostatSeparator1->setName( heliostatName1.toStdString().c_str() );

		//TSeparatorKit* heliostatSeparator2 = new TSeparatorKit;
		TSeparatorKit* heliostatSeparator2 = static_cast< TSeparatorKit* > ( separatorType.createInstance() );
		heliostatsNodePartList->addChild(heliostatSeparator2);
		QString heliostatName2 = QString( QLatin1String( "DivisionPor%1_2" ) ).arg( ( eje == 3 )? QString( 'Z' ): QString( 'X' ) );
		heliostatSeparator2->setName( heliostatName2.toStdString().c_str() );


		if( fabs( eje - 3 ) < 0.001 )
		{
			std::sort( heliostatCenterList.begin(), heliostatCenterList.end(), comparePuntosPorZ );

			std::vector< Point3D >::iterator it;

			double zMin = heliostatCenterList[0].z;
			double zMax = heliostatCenterList[nHeliostatCenters-1].z;

			double splitPoint = zMin + ( 0.5 * ( zMax - zMin ) );
			std::vector< Point3D > hCenterListPart1;
			double position = 0;
			while( ( position < heliostatCenterList.size() )
					&& ( heliostatCenterList[position].z < splitPoint ) )
			{
				hCenterListPart1.push_back( heliostatCenterList[position] );
				position++;
			}


			std::vector< Point3D > hCenterListPart2;
			while( position < heliostatCenterList.size() )
			{
				hCenterListPart2.push_back( heliostatCenterList[position] );
				position++;
			}
			CreateHeliostatZones( hCenterListPart1, heliostatSeparator1, heliostatTrackerFactory, aimingPoint, heliostatComponentNode, 1 );
			CreateHeliostatZones( hCenterListPart2, heliostatSeparator2, heliostatTrackerFactory, aimingPoint, heliostatComponentNode, 1 );

		}
		else
		{
			std::sort( heliostatCenterList.begin(), heliostatCenterList.end(), comparePuntosPorX );
			double xMin = heliostatCenterList[0].x;
			double xMax = heliostatCenterList[nHeliostatCenters-1].x;

			double splitPoint = xMin + ( 0.5 * ( xMax - xMin ) );
			std::vector< Point3D > hCenterListPart1;
			double position = 0;
			while( ( position < heliostatCenterList.size() )
					&& ( heliostatCenterList[position].x < splitPoint ) )
			{
				hCenterListPart1.push_back( heliostatCenterList[position] );
				position++;
			}


			std::vector< Point3D > hCenterListPart2;
			while( position < heliostatCenterList.size() )
			{
				hCenterListPart2.push_back( heliostatCenterList[position] );
				position++;
			}
			CreateHeliostatZones( hCenterListPart1, heliostatSeparator1, heliostatTrackerFactory, aimingPoint, heliostatComponentNode, 3 );
			CreateHeliostatZones( hCenterListPart2, heliostatSeparator2, heliostatTrackerFactory, aimingPoint, heliostatComponentNode, 3 );
		}


	}
}