Molecular Modeling Software
リビジョン | 2996f00e475da671cd49c9a433774505fcfbcd9d (tree) |
---|---|
日時 | 2014-09-09 01:11:57 |
作者 | toshinagata1964 <toshinagata1964@a2be...> |
コミッター | toshinagata1964 |
Molecule#insert_graphic is implemented. create/insert/remove_graphic are now undoable. (set_graphic_point/color are not yet.)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/molby/trunk@568 a2be9bc6-48de-4e38-9406-05402d4bc13c
@@ -91,6 +91,10 @@ static VALUE | ||
91 | 91 | s_CutoffSym, s_RadiusSym, s_ColorSym, s_FullNameSym, s_VdwRadiusSym, |
92 | 92 | s_CommentSym, s_SourceSym; |
93 | 93 | |
94 | +/* Symbols for graphics */ | |
95 | +static VALUE | |
96 | + s_LineSym, s_PolySym, s_CylinderSym, s_ConeSym, s_EllipsoidSym; | |
97 | + | |
94 | 98 | /* |
95 | 99 | * Utility function |
96 | 100 | * Get ary[i] by calling "[]" method |
@@ -9692,41 +9696,50 @@ s_Molecule_SetBackgroundColor(int argc, VALUE *argv, VALUE self) | ||
9692 | 9696 | |
9693 | 9697 | /* |
9694 | 9698 | * call-seq: |
9695 | - * create_graphic(kind, color, points, fill = nil) -> integer | |
9699 | + * insert_graphic(index, kind, color, points, fill = nil) -> integer | |
9696 | 9700 | * |
9697 | - * Create a new graphic object. | |
9701 | + * Create a new graphic object and insert at the given graphic index (if -1, then append at the last). | |
9698 | 9702 | * kind: a symbol representing the kind of the graphic. :line, :poly, :cylinder, :cone, :ellipsoid |
9699 | 9703 | * color: an array of 3 (rgb) or 4 (rgba) floating numbers |
9700 | 9704 | * points: an array of Vectors |
9701 | 9705 | * |
9702 | 9706 | */ |
9703 | 9707 | static VALUE |
9704 | -s_Molecule_CreateGraphic(int argc, VALUE *argv, VALUE self) | |
9708 | +s_Molecule_InsertGraphic(int argc, VALUE *argv, VALUE self) | |
9705 | 9709 | { |
9706 | 9710 | Molecule *mol; |
9707 | 9711 | MainViewGraphic g; |
9708 | - int i, n, ni; | |
9712 | + int i, n, ni, idx; | |
9709 | 9713 | const char *p; |
9710 | - VALUE kval, cval, pval, fval; | |
9714 | + VALUE kval, cval, pval, fval, ival; | |
9711 | 9715 | Data_Get_Struct(self, Molecule, mol); |
9712 | 9716 | if (mol->mview == NULL) |
9713 | 9717 | rb_raise(rb_eMolbyError, "this molecule has no associated graphic view"); |
9714 | - rb_scan_args(argc, argv, "31", &kval, &cval, &pval, &fval); | |
9715 | - kval = rb_obj_as_string(kval); | |
9718 | + rb_scan_args(argc, argv, "41", &ival, &kval, &cval, &pval, &fval); | |
9719 | + idx = NUM2INT(rb_Integer(ival)); | |
9720 | + if (idx == -1) | |
9721 | + idx = mol->mview->ngraphics; | |
9722 | + else if (idx < 0 || idx > mol->mview->ngraphics) | |
9723 | + rb_raise(rb_eMolbyError, "the graphic index (%d) out of range", idx); | |
9716 | 9724 | memset(&g, 0, sizeof(g)); |
9717 | 9725 | g.visible = 1; |
9718 | - p = RSTRING_PTR(kval); | |
9719 | - if (strcmp(p, "line") == 0) | |
9720 | - g.kind = kMainViewGraphicLine; | |
9721 | - else if (strcmp(p, "poly") == 0) | |
9722 | - g.kind = kMainViewGraphicPoly; | |
9723 | - else if (strcmp(p, "cylinder") == 0) | |
9724 | - g.kind = kMainViewGraphicCylinder; | |
9725 | - else if (strcmp(p, "cone") == 0) | |
9726 | - g.kind = kMainViewGraphicCone; | |
9727 | - else if (strcmp(p, "ellipsoid") == 0) | |
9728 | - g.kind = kMainViewGraphicEllipsoid; | |
9729 | - else rb_raise(rb_eMolbyError, "unknown graphic object type: %s", p); | |
9726 | + if (rb_obj_is_kind_of(kval, rb_cInteger)) { | |
9727 | + g.kind = NUM2INT(kval); /* Direct assign (for undo registration) */ | |
9728 | + } else { | |
9729 | + kval = rb_obj_as_string(kval); | |
9730 | + p = StringValuePtr(kval); | |
9731 | + if (strcmp(p, "line") == 0) | |
9732 | + g.kind = kMainViewGraphicLine; | |
9733 | + else if (strcmp(p, "poly") == 0) | |
9734 | + g.kind = kMainViewGraphicPoly; | |
9735 | + else if (strcmp(p, "cylinder") == 0) | |
9736 | + g.kind = kMainViewGraphicCylinder; | |
9737 | + else if (strcmp(p, "cone") == 0) | |
9738 | + g.kind = kMainViewGraphicCone; | |
9739 | + else if (strcmp(p, "ellipsoid") == 0) | |
9740 | + g.kind = kMainViewGraphicEllipsoid; | |
9741 | + else rb_raise(rb_eMolbyError, "unknown graphic object type: %s", p); | |
9742 | + } | |
9730 | 9743 | g.closed = (RTEST(fval) ? 1 : 0); |
9731 | 9744 | cval = rb_ary_to_ary(cval); |
9732 | 9745 | n = RARRAY_LEN(cval); |
@@ -9766,11 +9779,17 @@ s_Molecule_CreateGraphic(int argc, VALUE *argv, VALUE self) | ||
9766 | 9779 | NewArray(&g.points, &g.npoints, sizeof(GLfloat) * 3, n); |
9767 | 9780 | for (i = 0; i < n; i++) { |
9768 | 9781 | Vector v; |
9782 | + VALUE rval = RARRAY_PTR(pval)[i]; | |
9769 | 9783 | if (i == ni) { |
9770 | - v.x = NUM2DBL(rb_Float(RARRAY_PTR(pval)[i])); | |
9784 | + if (rb_obj_is_kind_of(rval, rb_cVector3D)) { | |
9785 | + /* The float argument can also be given as a vector (for simplify undo registration) */ | |
9786 | + VectorFromValue(rval, &v); | |
9787 | + } else { | |
9788 | + v.x = NUM2DBL(rb_Float(rval)); | |
9789 | + } | |
9771 | 9790 | v.y = v.z = 0; |
9772 | 9791 | } else { |
9773 | - VectorFromValue(RARRAY_PTR(pval)[i], &v); | |
9792 | + VectorFromValue(rval, &v); | |
9774 | 9793 | } |
9775 | 9794 | g.points[i * 3] = v.x; |
9776 | 9795 | g.points[i * 3 + 1] = v.y; |
@@ -9782,8 +9801,32 @@ s_Molecule_CreateGraphic(int argc, VALUE *argv, VALUE self) | ||
9782 | 9801 | g.points[6] = g.points[8] = g.points[9] = g.points[10] = 0; |
9783 | 9802 | g.points[7] = g.points[11] = g.points[3]; |
9784 | 9803 | } |
9785 | - MainView_insertGraphic(mol->mview, -1, &g); | |
9786 | - return INT2NUM(mol->mview->ngraphics - 1); | |
9804 | + MainView_insertGraphic(mol->mview, idx, &g); | |
9805 | + | |
9806 | + { | |
9807 | + /* Register undo */ | |
9808 | + MolAction *act; | |
9809 | + act = MolActionNew(SCRIPT_ACTION("i"), "remove_graphic", idx); | |
9810 | + MolActionCallback_registerUndo(mol, act); | |
9811 | + MolActionRelease(act); | |
9812 | + } | |
9813 | + | |
9814 | + return INT2NUM(idx); | |
9815 | +} | |
9816 | + | |
9817 | +/* | |
9818 | + * call-seq: | |
9819 | + * create_graphic(kind, color, points, fill = nil) -> integer | |
9820 | + * | |
9821 | + * Create a new graphic object. The arguments are similar as insert_graphic. | |
9822 | + */ | |
9823 | +static VALUE | |
9824 | +s_Molecule_CreateGraphic(int argc, VALUE *argv, VALUE self) | |
9825 | +{ | |
9826 | + VALUE args[5]; | |
9827 | + rb_scan_args(argc, argv, "31", args + 1, args + 2, args + 3, args + 4); | |
9828 | + args[0] = INT2NUM(-1); | |
9829 | + return s_Molecule_InsertGraphic(argc + 1, args, self); | |
9787 | 9830 | } |
9788 | 9831 | |
9789 | 9832 | /* |
@@ -9803,6 +9846,34 @@ s_Molecule_RemoveGraphic(VALUE self, VALUE ival) | ||
9803 | 9846 | i = NUM2INT(rb_Integer(ival)); |
9804 | 9847 | if (i < 0 || i >= mol->mview->ngraphics) |
9805 | 9848 | rb_raise(rb_eArgError, "graphic index is out of range"); |
9849 | + { | |
9850 | + /* Prepare data for undo */ | |
9851 | + MainViewGraphic *gp; | |
9852 | + Vector *vp; | |
9853 | + MolAction *act; | |
9854 | + double col[4]; | |
9855 | + int n; | |
9856 | + gp = mol->mview->graphics + i; | |
9857 | + vp = (Vector *)malloc(sizeof(Vector) * gp->npoints); | |
9858 | + for (n = 0; n < gp->npoints; n++) { | |
9859 | + vp[n].x = gp->points[n * 3]; | |
9860 | + vp[n].y = gp->points[n * 3 + 1]; | |
9861 | + vp[n].z = gp->points[n * 3 + 2]; | |
9862 | + } | |
9863 | + col[0] = gp->rgba[0]; | |
9864 | + col[1] = gp->rgba[1]; | |
9865 | + col[2] = gp->rgba[2]; | |
9866 | + col[3] = gp->rgba[3]; | |
9867 | + if (gp->visible == 0) { | |
9868 | + act = MolActionNew(SCRIPT_ACTION("i"), "hide_graphic", i); | |
9869 | + MolActionCallback_registerUndo(mol, act); | |
9870 | + MolActionRelease(act); | |
9871 | + } | |
9872 | + act = MolActionNew(SCRIPT_ACTION("iiDVb"), "insert_graphic", i, gp->kind, 4, col, gp->npoints, vp, gp->closed); | |
9873 | + MolActionCallback_registerUndo(mol, act); | |
9874 | + free(vp); | |
9875 | + MolActionRelease(act); | |
9876 | + } | |
9806 | 9877 | MainView_removeGraphic(mol->mview, i); |
9807 | 9878 | return ival; |
9808 | 9879 | } |
@@ -11586,6 +11657,7 @@ Init_Molby(void) | ||
11586 | 11657 | rb_define_method(rb_cMolecule, "set_view_center", s_Molecule_SetViewCenter, 1); |
11587 | 11658 | rb_define_method(rb_cMolecule, "set_background_color", s_Molecule_SetBackgroundColor, -1); |
11588 | 11659 | rb_define_method(rb_cMolecule, "create_graphic", s_Molecule_CreateGraphic, -1); |
11660 | + rb_define_method(rb_cMolecule, "insert_graphic", s_Molecule_InsertGraphic, -1); | |
11589 | 11661 | rb_define_method(rb_cMolecule, "remove_graphic", s_Molecule_RemoveGraphic, 1); |
11590 | 11662 | rb_define_method(rb_cMolecule, "ngraphics", s_Molecule_NGraphics, 0); |
11591 | 11663 | rb_define_method(rb_cMolecule, "set_graphic_point", s_Molecule_SetGraphicPoint, 3); |
@@ -11794,6 +11866,13 @@ Init_Molby(void) | ||
11794 | 11866 | g_RubyID_call = rb_intern("call"); |
11795 | 11867 | |
11796 | 11868 | s_InitMOInfoKeys(); |
11869 | + | |
11870 | + /* Symbols for graphics */ | |
11871 | + s_LineSym = ID2SYM(rb_intern("line")); | |
11872 | + s_PolySym = ID2SYM(rb_intern("poly")); | |
11873 | + s_CylinderSym = ID2SYM(rb_intern("cylinder")); | |
11874 | + s_ConeSym = ID2SYM(rb_intern("cone")); | |
11875 | + s_EllipsoidSym = ID2SYM(rb_intern("ellipsoid")); | |
11797 | 11876 | } |
11798 | 11877 | |
11799 | 11878 | #pragma mark ====== External functions ====== |