Exemple #1
0
msym_error_t findPermutation(msym_symmetry_operation_t *sop, int l, double (*v[l])[3], msym_thresholds_t *t, msym_permutation_t *perm){
    msym_error_t ret = MSYM_SUCCESS;
    double m[3][3];
    symmetryOperationMatrix(sop, m);
    
    perm->p = malloc(sizeof(int[l]));
    memset(perm->p, -1, sizeof(int[l])); //TODO: 2s complement
    perm->p_length = l;
    
    for(int i = 0; i < l;i++){
        int j;
        double r[3];
        mvmul(*v[i], m, r);
        for(j = 0;j < l;j++){
            if(vequal(r, *v[j],t->permutation)){
                perm->p[i] = j;
                break;
            }
        }
        if(j == l) {
            char buf[16];
            symmetryOperationName(sop, sizeof(buf), buf);
            msymSetErrorDetails("Unable to determine permutation for symmetry operation %s",buf);
            ret = MSYM_PERMUTATION_ERROR;
            goto err;
        }
    }
    if(MSYM_SUCCESS != (ret = setPermutationCycles(perm))) goto err;
    
    return ret;
    
err:
    free(perm->p);
    return ret;
}
Exemple #2
0
void gsrc_mousemove(int x, int y)
{
  float axis[3], angle;

  vassign( v1, 2.0*x/glutGet(GLUT_WINDOW_WIDTH)-1, -2.0*y/glutGet(GLUT_WINDOW_HEIGHT)+1, 1 );
  normalize(v1);
  if( vequal(v0,v1) )
    return;
  cross(axis,v0,v1);
  normalize(axis);
  angle = acosf( clamp(dot(v0,v1),-1,1) );
  vassign( v0, v1 );

  glPushMatrix();
    glLoadIdentity();
    glRotatef( angle*180/PI, axis[0], axis[1], axis[2] );
   // glTranslatef (axis[0], axis[1], axis[2]);
    //glScalef(1,1,1);
    //glTranslatef(-0.25, 0.5, 0.25);
   
        //glRotatef(3, axis[0], axis[1], axis[2]);
    
    //glScalef(1, 2, 1);
    glMultMatrixf( mo );
    glGetFloatv( GL_MODELVIEW_MATRIX, mo );
  glPopMatrix();
  glutPostRedisplay();
}
static bool intersectSegCountour(const int* d0, const int* d1, int i, int n, const int* verts)
{
	// For each edge (k,k+1) of P
	for (int k = 0; k < n; k++)
	{
		int k1 = next(k, n);
		// Skip edges incident to i.
		if (i == k || i == k1)
			continue;
		const int* p0 = &verts[k * 4];
		const int* p1 = &verts[k1 * 4];
		if (vequal(d0, p0) || vequal(d1, p0) || vequal(d0, p1) || vequal(d1, p1))
			continue;
		
		if (intersect(d0, d1, p0, p1))
			return true;
	}
	return false;
}
Exemple #4
0
// Returns T iff (v_i, v_j) is a proper internal *or* external
// diagonal of P, *ignoring edges incident to v_i and v_j*.
static bool diagonalie(int i, int j, int n, const int* verts, int* indices)
{
	const int* d0 = &verts[(indices[i] & 0x0fffffff) * 4];
	const int* d1 = &verts[(indices[j] & 0x0fffffff) * 4];
	
	// For each edge (k,k+1) of P
	for (int k = 0; k < n; k++)
	{
		int k1 = next(k, n);
		// Skip edges incident to i or j
		if (!((k == i) || (k1 == i) || (k == j) || (k1 == j)))
		{
			const int* p0 = &verts[(indices[k] & 0x0fffffff) * 4];
			const int* p1 = &verts[(indices[k1] & 0x0fffffff) * 4];

			if (vequal(d0, p0) || vequal(d1, p0) || vequal(d0, p1) || vequal(d1, p1))
				continue;
			
			if (intersect(d0, d1, p0, p1))
				return false;
		}
	}
	return true;
}
static void removeDegenerateSegments(rcIntArray& simplified)
{
	// Remove adjacent vertices which are equal on xz-plane,
	// or else the triangulator will get confused.
	int npts = simplified.size()/4;
	for (int i = 0; i < npts; ++i)
	{
		int ni = next(i, npts);
		
		if (vequal(&simplified[i*4], &simplified[ni*4]))
		{
			// Degenerate segment, remove.
			for (int j = i; j < simplified.size()/4-1; ++j)
			{
				simplified[j*4+0] = simplified[(j+1)*4+0];
				simplified[j*4+1] = simplified[(j+1)*4+1];
				simplified[j*4+2] = simplified[(j+1)*4+2];
				simplified[j*4+3] = simplified[(j+1)*4+3];
			}
			simplified.resize(simplified.size()-4);
			npts--;
		}
	}
}
//TODO: Use a preallocated pointer array instead of multiple mallocs
msym_error_t generateEquivalenceSet(msym_point_group_t *pg, int length, msym_element_t elements[length], int *glength, msym_element_t **gelements, int *esl, msym_equivalence_set_t **es,msym_thresholds_t *thresholds){
    msym_error_t ret = MSYM_SUCCESS;
    msym_element_t *ge = calloc(length,sizeof(msym_element_t[pg->order]));
    msym_equivalence_set_t *ges = calloc(length,sizeof(msym_equivalence_set_t));
    int gel = 0;
    int gesl = 0;
    for(int i = 0;i < length;i++){
        msym_equivalence_set_t *aes = NULL;
        int f;
        for(f = 0;f < gel;f++){
            if(ge[f].n == elements[i].n && ge[f].m == elements[i].m && 0 == strncmp(ge[f].name, elements[i].name, sizeof(ge[f].name)) && vequal(ge[f].v, elements[i].v, thresholds->permutation)){
                break;
            }
        }
        if(f == gel){
            aes = &ges[gesl++];
            aes->elements = calloc(pg->order,sizeof(msym_element_t*));
            aes->length = 0;
        } else {
            continue;
        }
        
        if(elements[i].aol > 0 || elements[i].ao != NULL){
            msymSetErrorDetails("Cannot (currently) generate equivalence sets from elements with orbitals");
            ret = MSYM_INVALID_ELEMENTS;
            goto err;
        }
        for(msym_symmetry_operation_t *s = pg->sops;s < (pg->sops + pg->sopsl);s++){
            double v[3];
            applySymmetryOperation(s, elements[i].v, v);
            
            for(f = 0;f < gel;f++){
                if(ge[f].n == elements[i].n && ge[f].m == elements[i].m && 0 == strncmp(ge[f].name, elements[i].name, sizeof(ge[f].name)) && vequal(ge[f].v, v, thresholds->permutation)){
                    break;
                }
            }
            if(f == gel){
                memcpy(&ge[gel],&elements[i],sizeof(msym_element_t));
                vcopy(v, ge[gel].v);
                aes->elements[aes->length++] = &ge[gel++];
            }
        }
        
        if(pg->order % aes->length != 0){
            msymSetErrorDetails("Equivalence set length (%d) not a divisor of point group order (%d)",pg->order);
            ret = MSYM_INVALID_EQUIVALENCE_SET;
            goto err;
        }
        
        aes->elements = realloc(aes->elements,sizeof(msym_element_t*[aes->length]));
    }
    
    msym_element_t *geo = ge;
    ge = realloc(ge,sizeof(msym_element_t[gel]));
    ges = realloc(ges,sizeof(msym_equivalence_set_t[gesl]) + sizeof(msym_element_t *[gel]));
    
    msym_element_t **ep = (msym_element_t **) &ges[gesl];
    for(int i = 0;i < gesl;i++){
        msym_element_t **tep = ep;
        for(int j = 0;j < ges[i].length;j++){
            *ep = ges[i].elements[j] - geo + ge;
            ep++;
        }
        free(ges[i].elements);
        ges[i].elements = tep;
    }

    *glength = gel;
    *gelements = ge;
    *es = ges;
    *esl = gesl;
    return ret;
    
err:
    free(ge);
    for(int i = 0; i < gesl;i++) free(ges[i].elements);
    free(ges);
    return ret;
}
msym_error_t partitionPointGroupEquivalenceSets(msym_point_group_t *pg, int length, msym_element_t *elements[length], msym_element_t *pelements[length], int *esl, msym_equivalence_set_t **es, msym_thresholds_t *thresholds){
    msym_error_t ret = MSYM_SUCCESS;
    msym_equivalence_set_t *ges = calloc(length,sizeof(msym_equivalence_set_t));
    int *eqi = malloc(sizeof(int[length]));
    memset(eqi,-1,sizeof(int[length]));
    int gesl = 0, pelementsl = 0;
    for(int i = 0;i < length;i++){
        if(eqi[i] >= 0) continue;
        if(pelementsl >= length){
            msymSetErrorDetails("Size of equivalence sets (%d) larger than number of elements (%d)",pelementsl,length);
            ret = MSYM_INVALID_EQUIVALENCE_SET;
            goto err;
        }
        
        msym_equivalence_set_t *aes = &ges[gesl++];
        aes->elements = &pelements[pelementsl];
        for(msym_symmetry_operation_t *s = pg->sops;s < (pg->sops + pg->sopsl);s++){
            double v[3];
            int f;
            applySymmetryOperation(s, elements[i]->v, v);
            for(f = 0;f < length;f++){
                if(elements[f]->n == elements[i]->n && elements[f]->m == elements[i]->m && 0 == strncmp(elements[f]->name, elements[i]->name, sizeof(elements[f]->name)) && vequal(elements[f]->v, v, thresholds->permutation)){
                    break;
                }
            }
            
            if(f < length && eqi[f] >= 0 && eqi[f] != gesl-1){
                char buf[64];
                symmetryOperationName(s, 64, buf);
                msymSetErrorDetails("Symmetry operation %s on element %d yeilded element (%d) in two diffenrent equivalence sets (%d and %d)",buf,i,f,eqi[f],gesl-1);
                ret = MSYM_INVALID_EQUIVALENCE_SET;
                goto err;
            } else if(f < length && eqi[f] == gesl-1){
                //printf("element[%d] %s belongs to equivalence set %d, but already added\n",f,elements[f]->name, eqi[f]);
            } else if(f < length){
                eqi[f] = gesl - 1;
                aes->elements[aes->length++] = elements[f];
                //printf("element[%d] %s belongs to equivalence set %d, adding\n",f,elements[f]->name, eqi[f]);
            } else {
                char buf[64];
                symmetryOperationName(s, 64, buf);
                msymSetErrorDetails("Cannot find permutation for %s when determining equivalence set from point group %s",buf,pg->name);
                ret = MSYM_INVALID_EQUIVALENCE_SET;
                goto err;
            }
        }
        //printf("generated equivalance set %d of length %d\n",gesl-1,aes->length);
        pelementsl += aes->length;
    }
    
    if(pelementsl != length){
        msymSetErrorDetails("Size of equivalence sets (%d) is not equal to number of elements (%d)",pelementsl,length);
        ret = MSYM_INVALID_EQUIVALENCE_SET;
        goto err;
    }
    
    *es = ges;
    *esl = gesl;
    
    free(eqi);
    return ret;
err:
    free(eqi);
    free(ges);
    return ret;

}