SAMSON Forum
    • Login
    • Search
    • Recent
    • Tags
    • Popular
    • SAMSON Connect
    • Get SAMSON

    Drawing arrows on atoms

    GUI
    3
    11
    6100
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • DmitriyMarin
      DmitriyMarin @Piriziwè last edited by

      @piriziwè For that you can use function SAMSON::displayCylinders.
      So, for example, one cylinder for the line and one cylinder for the arrow head with one of the radiuses set to zero. A line may also be drawn using SAMSON::displayLines.

      Dmitriy,
      The SAMSON Team, https://s-c.io

      1 Reply Last reply Reply Quote 0
      • G
        Guillaume last edited by Guillaume

        Hi @Piriziwè ,

        Here is an example code that you may use and that puts vertical arrows on every atom.

        
        void SEArrowDrawerVisualModel::display() {
        	// NodeIndexer that will receive the atoms
        	SBNodeIndexer nodes;
        	SAMSON::getActiveDocument()->getNodes(nodes, SBNode::IsType(Type::Atom));
        	// put all the atoms in the nodeIndexer
        	
        	//3d Arrows example
        	unsigned int nCylinders = 2 * nodes.size(); // we will need 2 cylinders by arrow, one for the head, one for the stick
        	unsigned int nPositions = 4 * nodes.size(); // 3 position by arrow, the two end points and the middle
        	unsigned int* indexData = new unsigned int[2 * nCylinders]; // this should be of size 2* cylinder, it will say for each end point at which position it should be
        	float *positionData = new float[3 * nPositions]; // all the coordinates X Y Z of each positions, 
        	float *radiusData = new float[2 * nCylinders]; // the radius of the two end points of the cylinder can be different to make a cone
        	unsigned int *capData = new unsigned int[2 * nCylinders]; // controls if the cylinders are closed or open
        	float *colorData = new float[4 * 2 * nCylinders]; // the ARGB code for each end point of a cylinder
        	unsigned int *flagData = new unsigned int[2 * nCylinders]; // controls if the cylinder is highlighted, selected
        	int atomCounter = 0;
        	SB_FOR(SBNode* n, nodes) {
        		SBAtom* atom = (SBAtom*) n;
        
        		SBVector3 arrowDirection(1, 0, 0);
        		SBQuantity::length arrowLength(60);
        
        		// give the position of the cone that is the head of the arrow
        		positionData[atomCounter * 12 + 0] = (atom->getPosition().v[0] + arrowDirection.v[0] * SAMSON::getAtomRadius()).getValue();
        		positionData[atomCounter * 12 + 1] = (atom->getPosition().v[1] + arrowDirection.v[1] * SAMSON::getAtomRadius()).getValue();
        		positionData[atomCounter * 12 + 2] = (atom->getPosition().v[2] + arrowDirection.v[2] * SAMSON::getAtomRadius()).getValue();
        		positionData[atomCounter * 12 + 3] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
        		positionData[atomCounter * 12 + 4] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
        		positionData[atomCounter * 12 + 5] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
        		// radii of the cone are 0 on the pointed size and 0 on the other side
        		radiusData[atomCounter * 4 + 0] = 0;
        		radiusData[atomCounter * 4 + 1] = 10;
        
        		// give the position of the cylinder that is the tail of the arrow
        		positionData[atomCounter * 12 + 6] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
        		positionData[atomCounter * 12 + 7] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
        		positionData[atomCounter * 12 + 8] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
        		positionData[atomCounter * 12 + 9] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + arrowLength)).getValue();
        		positionData[atomCounter * 12 + 10] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + arrowLength)).getValue();
        		positionData[atomCounter * 12 + 11] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + arrowLength)).getValue();
        		// radius of the tail is 2 everywhere
        		radiusData[atomCounter * 4 + 2] = 2;
        		radiusData[atomCounter * 4 + 3] = 2;
        
        		indexData[atomCounter * 4 + 0] = 4 * atomCounter + 0;
        		indexData[atomCounter * 4 + 1] = 4 * atomCounter + 1;
        		indexData[atomCounter * 4 + 2] = 4 * atomCounter + 2;
        		indexData[atomCounter * 4 + 3] = 4 * atomCounter + 3;
        
        		capData[atomCounter * 4 + 0] = 1;
        		capData[atomCounter * 4 + 1] = 1;
        		capData[atomCounter * 4 + 2] = 1;
        		capData[atomCounter * 4 + 3] = 1;
        
        
        		colorData[atomCounter * 16 + 0 ] = 1;
        		colorData[atomCounter * 16 + 1 ] = 1;
        		colorData[atomCounter * 16 + 2 ] = 1;
        		colorData[atomCounter * 16 + 3 ] = 1;
        		colorData[atomCounter * 16 + 4 ] = 1;
        		colorData[atomCounter * 16 + 5 ] = 1;
        		colorData[atomCounter * 16 + 6 ] = 1;
        		colorData[atomCounter * 16 + 7 ] = 1;
        		colorData[atomCounter * 16 + 8 ] = 1;
        		colorData[atomCounter * 16 + 9 ] = 1;
        		colorData[atomCounter * 16 + 10] = 1;
        		colorData[atomCounter * 16 + 11] = 1;
        		colorData[atomCounter * 16 + 12] = 1;
        		colorData[atomCounter * 16 + 13] = 1;
        		colorData[atomCounter * 16 + 14] = 1;
        		colorData[atomCounter * 16 + 15] = 1;
        
        		unsigned int flag = (atom->isSelected() ? 1 : 0) + (atom->isHighlighted() ? 2 : 0);
        		flagData[atomCounter * 4 + 0] = flag;
        		flagData[atomCounter * 4 + 1] = flag;
        		flagData[atomCounter * 4 + 2] = flag;
        		flagData[atomCounter * 4 + 3] = flag;
        		
        
        		atomCounter++;
        	}
        
        
        	SAMSON::displayCylinders(nCylinders, nPositions, indexData, positionData, radiusData, capData, colorData, flagData);
        
        	delete[] indexData;
        	delete[] radiusData;
        	delete[] capData;
        	delete[] colorData;
        	delete[] flagData;
        		
        }
        

        0_1513098165495_Untitled.png

        P 2 Replies Last reply Reply Quote 1
        • P
          Piriziwè @Guillaume last edited by

          @guillaume Hi,
          Thank you very much for this example. I will try it and send you a feedback.

          1 Reply Last reply Reply Quote 0
          • P
            Piriziwè @Guillaume last edited by

            Hi @guillaume, I tried your example above and it works correctly. But now I would like to call the visual model by code (on click event of a button) instead of doing it from SAMSON "Visualization->Add visual model" menu. I tried like adding a structural model but it does not work. Can you help me, please?

            Thank you.

            P 1 Reply Last reply Reply Quote 0
            • P
              Piriziwè @Piriziwè last edited by

              @Guillaume, It's done :) Thanks

              1 Reply Last reply Reply Quote 0
              • G
                Guillaume last edited by

                I'm glad you managed to do it, here is my solution if other people need it:

                
                SEMyVisualModel* vm = new SEMyVisualModel();// create your visual model
                SAMSON::beginHolding("Create visual model"); // this is to have this action undoable
                SAMSON::hold(vm); // Give the property of the object to SAMSON, you will not have to delete it when it will be removed
                vm->create();
                SAMSON::getActiveLayer()->addChild(vm); // add the visual model to a layer
                SAMSON::endHolding();
                
                P 1 Reply Last reply Reply Quote 1
                • P
                  Piriziwè @Guillaume last edited by

                  Hi @guillaume, please, I am facing a issue. Which paramters can I modify in order to get horizontal arrows or other directions arrows, please? Thank you in advance.

                  G 1 Reply Last reply Reply Quote 0
                  • G
                    Guillaume @Piriziwè last edited by

                    Hi @piriziwè ,

                    		SBVector3 arrowDirection(1, 0, 0);
                    		SBQuantity::length arrowLength(60);
                    
                    		// give the position of the cone that is the head of the arrow
                    		positionData[atomCounter * 12 + 0] = (atom->getPosition().v[0] + arrowDirection.v[0] * SAMSON::getAtomRadius()).getValue();
                    		positionData[atomCounter * 12 + 1] = (atom->getPosition().v[1] + arrowDirection.v[1] * SAMSON::getAtomRadius()).getValue();
                    		positionData[atomCounter * 12 + 2] = (atom->getPosition().v[2] + arrowDirection.v[2] * SAMSON::getAtomRadius()).getValue();
                    		positionData[atomCounter * 12 + 3] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
                    		positionData[atomCounter * 12 + 4] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
                    		positionData[atomCounter * 12 + 5] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
                    		// radii of the cone are 0 on the pointed size and 0 on the other side
                    		radiusData[atomCounter * 4 + 0] = 0;
                    		radiusData[atomCounter * 4 + 1] = 10;
                    
                    		// give the position of the cylinder that is the tail of the arrow
                    		positionData[atomCounter * 12 + 6] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
                    		positionData[atomCounter * 12 + 7] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
                    		positionData[atomCounter * 12 + 8] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + 0.3 * arrowLength)).getValue();
                    		positionData[atomCounter * 12 + 9] = (atom->getPosition().v[0] + arrowDirection.v[0] * (SAMSON::getAtomRadius() + arrowLength)).getValue();
                    		positionData[atomCounter * 12 + 10] = (atom->getPosition().v[1] + arrowDirection.v[1] * (SAMSON::getAtomRadius() + arrowLength)).getValue();
                    		positionData[atomCounter * 12 + 11] = (atom->getPosition().v[2] + arrowDirection.v[2] * (SAMSON::getAtomRadius() + arrowLength)).getValue();
                    		// radius of the tail is 2 everywhere
                    		radiusData[atomCounter * 4 + 2] = 2;
                    		radiusData[atomCounter * 4 + 3] = 2;
                    
                    

                    I did not detailed this par much, you can change the value of arrow direction to get the direction you want for the arrow. It can even be a different value for different atoms., I will update the first post as well

                    P 1 Reply Last reply Reply Quote 1
                    • P
                      Piriziwè @Guillaume last edited by

                      Thank you @guillaume. I will try it and see. Have a nice weekend

                      1 Reply Last reply Reply Quote 0
                      • P
                        Piriziwè last edited by

                        Hi everybody, all my problems with arrows are solved. Thanks very much for your help.

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post