_______________________________________________________________________________________________________________________________________ /*************************************************************************************************************************************/ /* */ /* F O N C T I O N S R A S T E R : */ /* */ /* */ /* Definition : */ /* */ /* Dans ce fichier, se trouvent toutes */ /* les fonctions d'acces du merveilleux */ /* CUBI7 en mode "raster". */ /* */ /* */ /* Author of '$xiidc/fonction.1$FON' : */ /* */ /* Jean-Francois Colonna (LACTAMME, 19870000000000). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* O P P O R T U N I T E D E C O M P I L E R C E M O D U L E : */ /* */ /*************************************************************************************************************************************/ #ifdef __VERSION__COMPILER_LE_GRAPHIQUE_CUBI7 /* Common,DEFV(Fonction,) : indicateur de VERSION. */ DEFV(Common,DEFV(Logical,_______VERSION__COMPILER_LE_GRAPHIQUE_CUBI7)); #Aifdef __VERSION__COMPILER_LE_GRAPHIQUE_CUBI7 /* Common,DEFV(Fonction,) : indicateur de VERSION. */ #Eifdef __VERSION__COMPILER_LE_GRAPHIQUE_CUBI7 /* Common,DEFV(Fonction,) : indicateur de VERSION. */ #ifdef __VERSION__COMPILER_LE_GRAPHIQUE_CUBI7 /* Common,DEFV(Fonction,) : la bibliotheque est conditionnelle... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* R E F E R E N C E S E X T E R N E S : */ /* */ /*************************************************************************************************************************************/ DEFV(Extern,DEFV(configuration,confhard)); /* Configuration materielle de la machine. */ DEFV(Extern,DEFV(vrai_Int_de_base,coderrc7)); /* Code d'erreur en retour des fonctions. */ DEFV(Extern,DEFV(vrai_Int_de_base,inititf())); /* Fonction d'initialisation du chemin d'acces a la CUBI7 (via le systeme */ /* et l'acces direct a la memoire). */ DEFV(Extern,DEFV(vrai_Int_de_base,format())); /* Fonction de definition de la definition (en nombre de lignes et nombre */ /* de points par ligne) de la memoire d'image. */ DEFV(Extern,DEFV(vrai_Int_de_base,aigmancou())); /* Fonction de definition des aiguillages de sortie (en visualisation) de la */ /* memoire d'image. */ DEFV(Extern,DEFV(vrai_Int_de_base,cadrage())); /* Fonction de definition de la position de l'image video par rapport */ /* aux signaux de synchornisation horizontales et verticales. */ DEFV(Extern,DEFV(vrai_Int_de_base,acces())); /* Fonction de definition de la memoire d'image accedee en generation */ /* et en visualisation. */ DEFV(Extern,DEFV(vrai_Int_de_base,accsupv())); /* Fonction de definition du mode d'acces a la memoire d'image. */ DEFV(Extern,DEFV(vrai_Int_de_base,selcou())); /* Fonction de definition des tables de coloriage utilisees et des eventuelles */ /* permutations de couleurs. */ DEFV(Extern,DEFV(vrai_Int_de_base,fond())); /* Fonction de definition de la valeur initiale des points lors d'une */ /* initialisation programmee de la memoire d'image. */ DEFV(Extern,DEFV(vrai_Int_de_base,selfond())); /* Fonction de definition de la source des valeurs initiales des points */ /* lors d'une initialisation de la memoire d'image. */ DEFV(Extern,DEFV(vrai_Int_de_base,razamd())); /* Fonction d'initialisation de la carte "AMD". */ DEFV(Extern,DEFV(vrai_Int_de_base,zeroad())); /* Initialisation du pointeur de micro-programme. */ DEFV(Extern,DEFV(vrai_Int_de_base,razgec())); /* Fonction d'initialisation de la carte "GEC". */ DEFV(Extern,DEFV(vrai_Int_de_base,imgec())); /* Fonction du choix du mode de fonctionnement de la carte "GEC". */ DEFV(Extern,DEFV(vrai_Int_de_base,ffgec())); /* Fonction du choix du mode de trace de la carte "GEC". */ DEFV(Extern,DEFV(vrai_Int_de_base,contges())); /* Fonction de programmation de la carte "GES". */ DEFV(Extern,DEFV(vrai_Int_de_base,emetpara())); /* Fonction d'envoi a la CUBI7 de l'ensemble (!!!) des parametres definissant */ /* son fonctionnement. */ DEFV(Extern,DEFV(vrai_Int_de_base,tstcarte())); /* Fonction de test de la presence physique des cartes de la machine. */ DEFV(Extern,DEFV(vrai_Int_de_base,effmem())); /* Fonction d'initialisation de l'ensemble des points de la memoire a l'aide */ /* du 'fond'. */ DEFV(Extern,DEFV(vrai_Int_de_base,tacou())); /* Fonction d'initialisation lineaire de la premiere table de couleur de chacun */ /* des deux groupes. */ DEFV(Extern,DEFV(vrai_Int_de_base,ecrirene())); /* Fonction de generation du fichier de configuration dans le directory courant... */ DEFV(Extern,DEFV(vrai_Int_de_base,ecrfenpix())); /* Fonction d'ecriture d'une fenetre de points (4 composantes). */ DEFV(Extern,DEFV(vrai_Int_de_base,ecrfencom())); /* Fonction d'ecriture d'une fenetre de points (1 seule composante parmi 4). */ DEFV(Extern,DEFV(vrai_Int_de_base,geff())); /* Fonction d'envoi d'une facette flottante. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* T E S T D E L ' E T A T E N E R R E U R D U C U B I 7 : */ /* */ /*************************************************************************************************************************************/ # define TEST_ERREUR_CUBI7 \ Bblock \ Test(IL_Y_A_ERREUR(coderrc7)) \ Bblock \ PRINT_ERREUR("le CUBI7 a un probleme (encore)"); \ CAL1(Prer1(" le code d'erreur vaut %d\n",coderrc7)); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Test du fonctionnement du CUBI7. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* E T A T V I D E O D E L ' I M A G E U R : */ /* */ /*************************************************************************************************************************************/ DEFV(Common,DEFV(Logical,SINT(CUBI7_____generer_de_la_video,FAUX))); /* Cet indicateur logique memorise la nature de la video demandee lors de l'open ; s'il */ /* est FAUX on est en 1024x1024 et s'il est VRAI on est en 576x700, c'est-a-dire que */ /* on genere de la video broadcast... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* C H O I X D U F O R M A T D E L ' I M A G E : */ /* */ /*************************************************************************************************************************************/ # define format7_512x512 \ /* Mise au format 512x512 : */ \ Bblock \ CALS(format(FORMAT_MEMOIRE_512x512)); \ /* Fonction de definition de la definition (en nombre de lignes et nombre */ \ /* de points par ligne) de la memoire d'image. */ \ CALS(aigmancou(MEMOIRE_512x512,GROUPE_0_DE_TABLES_DE_COLORIAGE)); \ /* Fonction de definition des aiguillages de sortie (en visualisation) de la */ \ /* memoire d'image. */ \ CALS(cadrage(23,219,48)); \ /* Fonction de definition de la position de l'image video par rapport */ \ /* aux signaux de synchronisation horizontales et verticales ; on trouve */ \ /* dans l'ordre les parametres 'Xcadrage', 'Ycadrage' et 'RETARD'. */ \ CALS(acces(MEMOIRE_512x512,MEMOIRE_512x512)); \ /* Fonction de definition de la memoire d'image accedee en generation */ \ /* et en visualisation ; on trouve dans l'ordre le numero de la memoire */ \ /* dans laquelle se fait la generation, puis celle a partir de laquelle */ \ /* se fait la visualisation. */ \ CALS(accsupv(COMPARAISON_EN_Z,ECRITURE_IMMEDIATE)); \ Eblock \ /* Fonction de definition du mode d'acces a la memoire d'image par le bus */ \ /* superviseur. */ # define format7_576x700 \ /* Mise au format 576x700 : */ \ Bblock \ CALS(format(FORMAT_MEMOIRE_576x700)); \ /* Fonction de definition de la definition (en nombre de lignes et nombre */ \ /* de points par ligne) de la memoire d'image. */ \ CALS(aigmancou(MEMOIRE_576x700,GROUPE_0_DE_TABLES_DE_COLORIAGE)); \ /* Fonction de definition des aiguillages de sortie (en visualisation) de la */ \ /* memoire d'image. */ \ CALS(cadrage(50,233,40)); \ /* Fonction de definition de la position de l'image video par rapport */ \ /* aux signaux de synchronisation horizontales et verticales ; on trouve */ \ /* dans l'ordre les parametres 'Xcadrage', 'Ycadrage' et 'RETARD'. */ \ CALS(acces(MEMOIRE_576x700,MEMOIRE_576x700)); \ /* Fonction de definition de la memoire d'image accedee en generation */ \ /* et en visualisation ; on trouve dans l'ordre le numero de la memoire */ \ /* dans laquelle se fait la generation, puis celle a partir de laquelle */ \ /* se fait la visualisation. */ \ CALS(accsupv(COMPARAISON_EN_Z,ECRITURE_IMMEDIATE)); \ Eblock \ /* Fonction de definition du mode d'acces a la memoire d'image par le bus */ \ /* superviseur. */ # define format7_1024x1024 \ /* Mise au format 1024x1024 : */ \ Bblock \ CALS(format(FORMAT_MEMOIRE_1024x1024)); \ /* Fonction de definition de la definition (en nombre de lignes et nombre */ \ /* de points par ligne) de la memoire d'image. */ \ CALS(aigmancou(MEMOIRE_1024x1024,GROUPE_0_DE_TABLES_DE_COLORIAGE)); \ /* Fonction de definition des aiguillages de sortie (en visualisation) de la */ \ /* memoire d'image. */ \ CALS(cadrage(157,236,63)); \ /* Fonction de definition de la position de l'image video par rapport */ \ /* aux signaux de synchronisation horizontales et verticales ; on trouve */ \ /* dans l'ordre les parametres 'Xcadrage', 'Ycadrage' et 'RETARD'. */ \ CALS(acces(MEMOIRE_1024x1024,MEMOIRE_1024x1024)); \ /* Fonction de definition de la memoire d'image accedee en generation */ \ /* et en visualisation ; on trouve dans l'ordre le numero de la memoire */ \ /* dans laquelle se fait la generation, puis celle a partir de laquelle */ \ /* se fait la visualisation. */ \ CALS(accsupv(COMPARAISON_EN_Z,ECRITURE_IMMEDIATE)); \ Eblock \ /* Fonction de definition du mode d'acces a la memoire d'image par le bus */ \ /* superviseur. */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* I N I T I A L I S A T I O N D E L ' I M A G E U R : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,I7open(initialisation_generale,generer_de_la_video,generer_le_fichier_de_configuration))) DEFV(Argument,DEFV(Logical,initialisation_generale)); /* Cet indicateur demande une initialisation generale ('VRAI') ou */ /* partielle ('FAUX') de la machine. */ DEFV(Argument,DEFV(Logical,generer_de_la_video)); /* Cet indicateur precise si l'on doit generer de la video 625 lignes ('VRAI'), ou */ /* bien des signaux "haute-definition" 1024 lignes ('FAUX'). */ DEFV(Argument,DEFV(Logical,generer_le_fichier_de_configuration)); /* Cet indicateur precise si l'on doit generer le fichier de configuration ('VRAI') */ /* appele "irene" dans le directory courant (...), ou pas ('FAUX')... */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /*..............................................................................................................................*/ EGAL(CUBI7_____generer_de_la_video,generer_de_la_video); /* Cet indicateur logique memorise la nature de la video demandee lors de l'open ; s'il */ /* est FAUX on est en 1024x1024 et s'il est VRAI on est en 576x700, c'est-a-dire que */ /* on genere de la video broadcast... */ CALS(inititf()); /* Fonction d'initialisation du chemin d'acces a la CUBI7 (via le systeme */ /* et l'acces direct a la memoire). */ /* Nota : sur le SPS9, l'initialisation CALS(inititf()) avait lieu plus */ /* bas, car en effet, chacune des fonctions suivantes executaient un 'emetpara' */ /* qui envoyait systematiquement tous les parametres a la CUBI7, or tant qu'ils */ /* n'ont pas tous ete initialises en memoire, l'initialisation ne peut etre */ /* que partielle, et provoquait donc de mauvaises programmations (temporaires) */ /* de la CUBI7... Or malheureusement, sur le DPX5000, cette methode ne fonctionne */ /* pas et j'ignore pourquoi... Donc, l'initialisation doit se faire en premier... */ /* Mais j'ai modifie la bibliotheque, et depuis, tant que la fonction 'selfond' n'a pas */ /* ete appelee, les appels a 'emetpara' sont ineffectifs... */ Test(IL_FAUT(CUBI7_____generer_de_la_video)) Bblock format7_576x700; /* Mise de la machine au format 576x700 (video "standard"), */ Eblock ATes Bblock format7_1024x1024; /* Mise de la machine au format 1024x1024 ("haute-definition"). */ Eblock ETes CALS(selcou(couleur_ROUGE,couleur_VERTE,couleur_BLEUE,GROUPE_0_DE_TABLES_DE_COLORIAGE,TABLE_DE_COLORIAGE_0)); /* Fonction de definition des tables de coloriage utilisees et des eventuelles */ /* permutations de couleurs pour le groupe 0, */ CALS(selcou(couleur_ROUGE,couleur_VERTE,couleur_BLEUE,GROUPE_1_DE_TABLES_DE_COLORIAGE,TABLE_DE_COLORIAGE_0)); /* Fonction de definition des tables de coloriage utilisees et des eventuelles */ /* permutations de couleurs pour le groupe 1. */ CALS(fond(Zinfini7,NOIR7,NOIR7,NOIR7)); /* Fonction de definition de la valeur initiale des points lors d'une */ /* initialisation programmee de la memoire d'image (registre 'fond'). */ CALS(selfond(RVB_INITIALISATION_FOND,Z_INITIALISATION_FOND)); /* Fonction de definition de la source des valeurs initiales des points */ /* lors d'une initialisation de la memoire d'image (cette source est le */ /* registre 'fond' defini ci-dessus). */ /* Nota : sur le SPS9, l'initialisation CALS(inititf()) n'avait lieu */ /* qu'ici car en effet, chacune des fonctions precedentes executaient un 'emetpara' */ /* qui envoyait systematiquement tous les parametres a la CUBI7, or tant qu'ils */ /* n'ont pas tous ete initialises en memoire, l'initialisation ne peut etre */ /* que partielle, et provoquait donc de mauvaises programmations (temporaires) */ /* de la CUBI7... Or malheureusement, sur le DPX5000, cette methode ne fonctionne */ /* pas et j'ignore pourquoi... */ /* Nota : c'est la fonction 'selfond' qui debloque le fonctionnement de 'emetpara'... */ EGAL(ASD1(confhard,AMD_present),COND(PRESENT(tstcarte(carte_AMD)),EXIST,NEXIST)); EGAL(ASD1(confhard,GEC_present),COND(PRESENT(tstcarte(carte_GEC)),EXIST,NEXIST)); EGAL(ASD1(confhard,GES_present),COND(PRESENT(tstcarte(carte_GES)),EXIST,NEXIST)); /* Test de la presence physique des trois cartes 'AMD', 'GEC' et 'GES'. */ EGAL(ASD1(confhard,utiliser_AMD),ASD1(confhard,AMD_present)); EGAL(ASD1(confhard,utiliser_GEC),ASD1(confhard,GEC_present)); EGAL(ASD1(confhard,utiliser_GES),ASD1(confhard,GES_present)); /* Si les trois cartes 'AMD', 'GEC' et 'GES' sont presentes, on les utilisera. */ EGAL(ASD1(confhard,AMD_present_et_l_utiliser),ETLO(ASD1(confhard,AMD_present),ASD1(confhard,utiliser_AMD))); EGAL(ASD1(confhard,GEC_present_et_l_utiliser),ETLO(ASD1(confhard,GEC_present),ASD1(confhard,utiliser_GEC))); EGAL(ASD1(confhard,GES_present_et_l_utiliser),ETLO(ASD1(confhard,GES_present),ASD1(confhard,utiliser_GES))); /* Test de l'utilisation des trois cartes 'AMD', 'GEC' et 'GES'. */ CALS(razamd()); /* Fonction d'initialisation de la carte "AMD", */ CALS(zeroad()); /* Et initialisation du pointeur de micro-programme. */ CALS(razgec()); /* Fonction d'initialisation de la carte "GEC", et */ CALS(ffgec(FACETTES_REMPLIES)); /* Fonction de choix du mode de trace de la carte "GEC". */ CALS(imgec(MODE_IMAGE)); /* Fonction de choix du mode de fonctionnement de la carte "GEC" ; on demande */ /* ainsi a tracer les lignes paires et impaires de chaque image. */ CALS(contges(COMPARAISON_EN_Z,PAS_D_ANTI_ALIASING)); /* Fonction de programmation de la carte "GES". */ Test(IL_FAUT(initialisation_generale)) Bblock CALS(effmem()); /* Fonction d'initialisation de l'ensemble des points de la memoire a l'aide */ /* du 'fond'. */ CALS(tacou()); /* Fonction d'initialisation lineaire de la premiere table de couleur de chacun */ /* des deux groupes. */ Eblock ATes Bblock Eblock ETes Test(IL_FAUT(generer_le_fichier_de_configuration)) Bblock CALS(ecrirene()); /* Generation du fichier de configuration dans le directory courant... */ Eblock ATes Bblock Eblock ETes TEST_ERREUR_CUBI7; RETU_ERROR; Eblock EFonctionI # undef format7_1024x1024 # undef format7_576x700 # undef format7_512x512 /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* " F E R M E T U R E " D E L ' I M A G E U R : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,I7close())) /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; /*..............................................................................................................................*/ RETU_ERROR; Eblock EFonctionI /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* E N V O I D ' U N E I M A G E ( R , V , B , Z ) E N M O D E */ /* " P I X E L S " D A N S U N E F E N E T R E B I _ D I M E N S I O N N E L L E : */ /* */ /*************************************************************************************************************************************/ BFonctionI DEFV(Common,DEFV(FonctionI,I7fenetre_2D(image_ROUGE,image_VERTE,image_BLEUE ,coordonnee_Z ,ARGUMENT_POINTERs(translation) ,ARGUMENT_POINTERs(taille) ,optimiser ) ) ) DEFV(Argument,DEFV(image,image_ROUGE)); /* Composante rouge, */ DEFV(Argument,DEFV(image,image_VERTE)); /* Composante verte, */ DEFV(Argument,DEFV(image,image_BLEUE)); /* Composante bleue, */ DEFV(Argument,DEFV(Int,coordonnee_Z)); /* Coordonnee 'Z' a attribuer a tous les points de la fenetre. */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(translation))); /* Translation a apporter a la fenetre dans la memoire ; celle-ci est */ /* exprimee dans des coordonnees telles que l'unite represente la dimension */ /* maximale du plan de travail du CUBI7. */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(taille))); /* Taille de la fenetre dans la memoire ; celle-ci est exprimee dans des */ /* coordonnees telles que l'unite represente la dimension maximale du plan */ /* de travail du CUBI7. */ DEFV(Argument,DEFV(Logical,optimiser)); /* Cet indicateur precise s'il faut optimiser ('VRAI') ou pas ('FAUX') les */ /* transferts ; l'optimisation consiste a ne pas transmettre les octets 'dummy' */ /* accompagnant chaque composante {R,V,B}. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; DEFV(fenetre7,fenetre); /* Fenetre a afficher sur l'ecran. */ DEFV(Int,INIT(Xmin_fenetre,Xmin)); /* Definition de l'abscisse origine de la fenetre, */ DEFV(Int,INIT(Ymin_fenetre,Ymin)); /* Definition de l'ordonnee origine de la fenetre. */ DEFV(Int,INIT(dimX_fenetre,TRON(_lDENORMALISE_OX7(ASI1(taille,dx)),PasX,dimX))); /* Taille horizontale de la fenetre, */ DEFV(Int,INIT(dimY_fenetre,TRON(_lDENORMALISE_OY7(ASI1(taille,dy)),PasY,dimY))); /* Taille verticale de la fenetre. */ DEFV(Int,INIT(Xposition_fenetre,_lDENORMALISE_OX7(ASI1(translation,dx)))); /* Definition de la position horizontale de la fenetre, */ DEFV(Int,INIT(Yposition_fenetre,UNDEF)); /* Definition de la position verticale de la fenetre. */ DEFV(Int,INIT(X,UNDEF)); DEFV(Int,INIT(Y,UNDEF)); /* Coordonnees entieres 'X' et 'Y' dans la fenetre. */ DEFV(Float,INIT(Xf,FLOT__UNDEF)); DEFV(Float,INIT(Yf,FLOT__UNDEF)); /* Coordonnees 'X' et 'Y' de l'image a mettre dans la fenetre. */ DEFV(Float,INIT(pasX_fenetre,FLOT__UNDEF)); /* Pas de parcours horizontal des images ROUGE, VERTE et BLEUE ; nota : */ /* l'initialisation n'est plus faite dans les donnees de peur que le */ /* compilateur (vue la dependance entre 'dimX_fenetre' et 'pasX_fenetre') */ /* ne genere un code incorrect... */ DEFV(Float,INIT(pasY_fenetre,FLOT__UNDEF)); /* Pas de parcours vertical des images ROUGE, VERTE et BLEUE ; nota : */ /* l'initialisation n'est plus faite dans les donnees de peur que le */ /* compilateur (vue la dependance entre 'dimY_fenetre' et 'pasY_fenetre') */ /* ne genere un code incorrect... */ DEFV(genere_ROUGE,INIT(point_ROUGE_courant,NIVEAU_UNDEF)); /* Point courant de la composante ROUGE lors de la generation de la fenetre. */ DEFV(genere_VERTE,INIT(point_VERTE_courant,NIVEAU_UNDEF)); /* Point courant de la composante VERTE lors de la generation de la fenetre. */ DEFV(genere_BLEUE,INIT(point_BLEUE_courant,NIVEAU_UNDEF)); /* Point courant de la composante BLEUE lors de la generation de la fenetre. */ /*..............................................................................................................................*/ EGAL(Yposition_fenetre ,INTE(SOUS(SOUS(FLOT(dimY7) ,FLOT(dimY_fenetre) ) ,FLOT(_lDENORMALISE_OY7(ASI1(translation,dy))) ) ) ); /* Definition de la position verticale de la fenetre. */ EGAL(pasX_fenetre,TRON(DIVI(FLOT(dimX),FLOT(dimX_fenetre)),FLOT(PasX),FLOT(dimX))); /* Pas de parcours horizontal des images ROUGE, VERTE et BLEUE. */ EGAL(pasY_fenetre,TRON(DIVI(FLOT(dimY),FLOT(dimY_fenetre)),FLOT(PasY),FLOT(dimY))); /* Pas de parcours vertical des images ROUGE, VERTE et BLEUE. */ DoIn(Yf,FLOT(Ymin),FLOT(Ymax),pasY_fenetre) Bblock EGAL(Y ,INTE(COYA(DIVI(SOUS(FLOT(Ymax),Yf) ,pasY_fenetre ) ) ) ); /* Calcul de l'ordonnee dans la fenetre. */ DoIn(Xf,FLOT(Xmin),FLOT(Xmax),pasX_fenetre) Bblock EGAL(X ,INTE(COXA(DIVI(SOUS(Xf,FLOT(Xmin)) ,pasX_fenetre ) ) ) ); /* Calcul de l'abscisse dans la fenetre. */ EGAL(point_ROUGE_courant,CARA(load_point(image_ROUGE,INTE(Xf),INTE(Yf)))); EGAL(point_VERTE_courant,CARA(load_point(image_VERTE,INTE(Xf),INTE(Yf)))); EGAL(point_BLEUE_courant,CARA(load_point(image_BLEUE,INTE(Xf),INTE(Yf)))); /* Recuperation du point courant des composantes ROUGE, VERTE et BLEUE */ /* avec le maillage et la translation courants. */ PUSH_TRANSLATION; SET_TRANSLATION(TraX,TraY); PUSH_ECHANTILLONNAGE; SET_ECHANTILLONNAGE(PasX,PasY); /* Mise en place du maillage de base, sans translation. */ EGAL(ASD1(IMAGE(fenetre,X,Y),zed),SHOR(coordonnee_Z)); /* Transfert de la troisieme coordonnee. */ EGAL(ASD2(IMAGE(fenetre,X,Y),rouge,niveau),point_ROUGE_courant); /* Transfert du point courant de la composante ROUGE dans la fenetre. */ EGAL(ASD2(IMAGE(fenetre,X,Y),verte,niveau),point_VERTE_courant); /* Transfert du point courant de la composante VERTE dans la fenetre. */ EGAL(ASD2(IMAGE(fenetre,X,Y),bleue,niveau),point_BLEUE_courant); /* Transfert du point courant de la composante BLEUE dans la fenetre. */ Test(IL_NE_FAUT_PAS(optimiser)) Bblock EGAL(ASD2(IMAGE(fenetre,X,Y),rouge,dummy),CARA(NOIR)); /* Par pure maniaquerie... */ EGAL(ASD2(IMAGE(fenetre,X,Y),verte,dummy),CARA(NOIR)); /* Par pure maniaquerie... */ EGAL(ASD2(IMAGE(fenetre,X,Y),bleue,dummy),CARA(NOIR)); /* Par pure maniaquerie... */ Eblock ATes Bblock Eblock ETes PULL_ECHANTILLONNAGE; PULL_TRANSLATION; /* Enfin, restauration du maillage courant... */ Eblock EDoI Eblock EDoI Test(IL_Y_A_ERREUR(ecrfenpix(fenetre ,dimX ,ADRESSE(Xmin_fenetre),ADRESSE(Ymin_fenetre) ,ADRESSE(dimX_fenetre),ADRESSE(dimY_fenetre) ,COND(IL_FAUT(CUBI7_____generer_de_la_video) ,MEMOIRE_576x700 ,MEMOIRE_1024x1024 ) ,ADRESSE(Xposition_fenetre),ADRESSE(Yposition_fenetre) ,COMPARAISON_EN_Z ) ) ) /* Et transfert de l'image en vraies couleurs. */ Bblock PRINT_ERREUR("probleme lors de l'ecriture d'une fenetre"); Eblock ATes Bblock Eblock ETes RETU_ERROR; Eblock EFonctionI /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* E N V O I D ' U N E C O M P O S A N T E ( R , V , B ) E N M O D E */ /* " P I X E L S " D A N S U N E F E N E T R E B I _ D I M E N S I O N N E L L E : */ /* */ /*************************************************************************************************************************************/ BFonctionI # define TRAITEMENT_COMPOSANTE(composante_RVB) \ Ca1e(composante_RVB) \ Bblock \ DoIn(Yf,FLOT(Ymin),FLOT(Ymax),pasY_fenetre) \ Bblock \ EGAL(Y \ ,INTE(COYA(DIVI(SOUS(FLOT(Ymax),Yf) \ ,pasY_fenetre \ ) \ ) \ ) \ ); \ /* Calcul de l'ordonnee dans la fenetre. */ \ DoIn(Xf,FLOT(Xmin),FLOT(Xmax),pasX_fenetre) \ Bblock \ EGAL(X \ ,INTE(COXA(DIVI(SOUS(Xf,FLOT(Xmin)) \ ,pasX_fenetre \ ) \ ) \ ) \ ); \ /* Calcul de l'abscisse dans la fenetre. */ \ EGAL(point_courant,CARA(load_point(imageA,INTE(Xf),INTE(Yf)))); \ /* Recuperation du point courant de la composante avec le maillage et */ \ /* la translation courants. */ \ PUSH_TRANSLATION; \ SET_TRANSLATION(TraX,TraY); \ PUSH_ECHANTILLONNAGE; \ SET_ECHANTILLONNAGE(PasX,PasY); \ /* Mise en place du maillage de base, sans translation. */ \ EGAL(ASD1(IMAGE(fenetre,X,Y),niveau),point_courant); \ /* Transfert du point courant de la composante dans la fenetre. */ \ Test(IL_NE_FAUT_PAS(optimiser)) \ Bblock \ EGAL(ASD1(IMAGE(fenetre,X,Y),dummy),CARA(NOIR)); \ /* Par pure maniaquerie... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ PULL_ECHANTILLONNAGE; \ PULL_TRANSLATION; \ /* Enfin, restauration du maillage courant... */ \ Eblock \ EDoI \ Eblock \ EDoI \ \ Test(IL_Y_A_ERREUR(ecrfencom(fenetre \ ,dimX \ ,ADRESSE(Xmin_fenetre),ADRESSE(Ymin_fenetre) \ ,ADRESSE(dimX_fenetre),ADRESSE(dimY_fenetre) \ ,COND(IL_FAUT(CUBI7_____generer_de_la_video) \ ,MEMOIRE_576x700 \ ,MEMOIRE_1024x1024 \ ) \ ,ADRESSE(Xposition_fenetre),ADRESSE(Yposition_fenetre) \ ,composante_RVB \ ) \ ) \ ) \ /* Et transfert de la composante. */ \ Bblock \ PRINT_ERREUR("probleme lors de l'ecriture d'une composante d'une fenetre"); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ ECa1 DEFV(Common,DEFV(FonctionI,I7fenetre_RVB(imageA,composante ,ARGUMENT_POINTERs(translation) ,ARGUMENT_POINTERs(taille) ,optimiser ) ) ) DEFV(Argument,DEFV(image,imageA)); /* Composante a envoyer dans la fenetre, */ DEFV(Argument,DEFV(Int,composante)); /* Et son identificateur ('composante_XXX'). */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(translation))); /* Translation a apporter a la fenetre dans la memoire ; celle-ci est */ /* exprimee dans des coordonnees telles que l'unite represente la dimension */ /* maximale du plan de travail du CUBI7. */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(taille))); /* Taille de la fenetre dans la memoire ; celle-ci est exprimee dans des */ /* coordonnees telles que l'unite represente la dimension maximale du plan */ /* de travail du CUBI7. */ DEFV(Argument,DEFV(Logical,optimiser)); /* Cet indicateur precise s'il faut optimiser ('VRAI') ou pas ('FAUX') les */ /* transferts ; l'optimisation consiste a ne pas transmettre les octets 'dummy' */ /* accompagnant chaque composante {R,V,B}. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; DEFV(composante7,fenetre); /* Composante de la fenetre a afficher sur l'ecran. */ DEFV(Int,INIT(Xmin_fenetre,Xmin)); /* Definition de l'abscisse origine de la fenetre, */ DEFV(Int,INIT(Ymin_fenetre,Ymin)); /* Definition de l'ordonnee origine de la fenetre. */ DEFV(Int,INIT(dimX_fenetre,TRON(_lDENORMALISE_OX7(ASI1(taille,dx)),PasX,dimX))); /* Taille horizontale de la fenetre, */ DEFV(Int,INIT(dimY_fenetre,TRON(_lDENORMALISE_OY7(ASI1(taille,dy)),PasY,dimY))); /* Taille verticale de la fenetre. */ DEFV(Int,INIT(Xposition_fenetre,_lDENORMALISE_OX7(ASI1(translation,dx)))); /* Definition de la position horizontale de la fenetre, */ DEFV(Int,INIT(Yposition_fenetre,UNDEF)); /* Definition de la position verticale de la fenetre ; nota : */ /* l'initialisation n'est plus faite dans les donnees de peur que le */ /* compilateur (vue la dependance entre 'dimY_fenetre' et 'Yposition_fenetre') */ /* ne genere un code incorrect... */ DEFV(Int,INIT(X,UNDEF)); DEFV(Int,INIT(Y,UNDEF)); /* Coordonnees entieres 'X' et 'Y' dans la fenetre. */ DEFV(Float,INIT(Xf,FLOT__UNDEF)); DEFV(Float,INIT(Yf,FLOT__UNDEF)); /* Coordonnees 'X' et 'Y' de l'image a mettre dans la fenetre. */ DEFV(Float,INIT(pasX_fenetre,FLOT__UNDEF)); /* Pas de parcours horizontal des images ROUGE, VERTE et BLEUE ; nota : */ /* l'initialisation n'est plus faite dans les donnees de peur que le */ /* compilateur (vue la dependance entre 'dimX_fenetre' et 'pasX_fenetre') */ /* ne genere un code incorrect... */ DEFV(Float,INIT(pasY_fenetre,FLOT__UNDEF)); /* Pas de parcours vertical des images ROUGE, VERTE et BLEUE ; nota : */ /* l'initialisation n'est plus faite dans les donnees de peur que le */ /* compilateur (vue la dependance entre 'dimY_fenetre' et 'pasY_fenetre') */ /* ne genere un code incorrect... */ DEFV(genere_RVB,INIT(point_courant,NIVEAU_UNDEF)); /* Point courant de la composante lors de la generation de la fenetre. */ /*..............................................................................................................................*/ EGAL(Yposition_fenetre ,INTE(SOUS(SOUS(FLOT(dimY7) ,FLOT(dimY_fenetre) ) ,FLOT(_lDENORMALISE_OY7(ASI1(translation,dy))) ) ) ); /* Definition de la position verticale de la fenetre. */ EGAL(pasX_fenetre,TRON(DIVI(FLOT(dimX),FLOT(dimX_fenetre)),FLOT(PasX),FLOT(dimX))); /* Pas de parcours horizontal des images ROUGE, VERTE et BLEUE. */ EGAL(pasY_fenetre,TRON(DIVI(FLOT(dimY),FLOT(dimY_fenetre)),FLOT(PasY),FLOT(dimY))); /* Pas de parcours vertical des images ROUGE, VERTE et BLEUE. */ Choi(composante) Bblock TRAITEMENT_COMPOSANTE(composante_ROUGE) TRAITEMENT_COMPOSANTE(composante_VERTE) TRAITEMENT_COMPOSANTE(composante_BLEUE) Defo Bblock PRINT_ERREUR("une composante inexistante a ete demandee"); Eblock EDef Eblock ECho RETU_ERROR; Eblock # undef TRAITEMENT_COMPOSANTE EFonctionI /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* E N V O I D ' U N E I M A G E ( R , V , B , Z ) E N M O D E */ /* " F A C E T T E S " D A N S U N E F E N E T R E T R I _ D I M E N S I O N N E L L E : */ /* */ /*************************************************************************************************************************************/ BFonctionI # define GENERATION_FACETTE_CARREE(facette,sommet,Sx,Sy,Sz) \ Bblock \ INITIALISATION_POINT_3D(ITb1(facette,INDX(sommet,PREMIER_SOMMET)) \ ,TRON(C7XA(ADD2(MUL2(HOMOTHETIE_HORIZONTALE_CUBI7(ASI1(taille,dx)) \ ,FLOT(COXR(Sx)) \ ) \ ,_lDENORMALISE_OX7(ASI1(translation,dx)) \ ) \ ) \ ,FLOT(Xmin7) \ ,FLOT(Xmax7_700) \ ) \ ,TRON(C7YA(SOUS(FLOT(Ymax7_576) \ ,ADD2(MUL2(HOMOTHETIE_VERTICALE_CUBI7(ASI1(taille,dy)) \ ,FLOT(COYR(Sy)) \ ) \ ,_lDENORMALISE_OY7(ASI1(translation,dy)) \ ) \ ) \ ) \ ,FLOT(Ymin7) \ ,FLOT(Ymax7_576) \ ) \ ,FLOT(Sz) \ ); \ /* Mise en place des coordonnees flottantes (Sx,Sy,Sz) du sommet */ \ /* courant de la facette ; on n'oubliera pas que l'axe 'OY' du */ \ /* CUBI7 est a l'envers... */ \ EGAL(ASD1(ITb1(facette,INDX(sommet,PREMIER_SOMMET)),cR) \ ,FLOT(load_point(image_ROUGE,Sx,Sy)) \ ); \ EGAL(ASD1(ITb1(facette,INDX(sommet,PREMIER_SOMMET)),cV) \ ,FLOT(load_point(image_VERTE,Sx,Sy)) \ ); \ EGAL(ASD1(ITb1(facette,INDX(sommet,PREMIER_SOMMET)),cB) \ ,FLOT(load_point(image_BLEUE,Sx,Sy)) \ ); \ /* Mise en place des composantes (ROUGE,VERTE,BLEUE) du sommet courant */ \ /* de la facette. */ \ Eblock \ /* Generation du sommet courant d'une facette flottante. */ DEFV(Common,DEFV(FonctionI,I7fenetre_3D(image_ROUGE,image_VERTE,image_BLEUE ,coordonnee_Z ,ARGUMENT_POINTERs(translation) ,ARGUMENT_POINTERs(taille) ) ) ) DEFV(Argument,DEFV(image,image_ROUGE)); /* Composante rouge, */ DEFV(Argument,DEFV(image,image_VERTE)); /* Composante verte, */ DEFV(Argument,DEFV(image,image_BLEUE)); /* Composante bleue, */ DEFV(Argument,DEFV(Positive,coordonnee_Z)); /* Coordonnee 'Z' a attribuer a tous les points de la fenetre. */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(translation))); /* Translation a apporter a la fenetre dans la memoire ; celle-ci est */ /* exprimee dans des coordonnees telles que l'unite represente la dimension */ /* maximale du plan de travail du CUBI7. */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(taille))); /* Taille de la fenetre dans la memoire ; celle-ci est exprimee dans des */ /* coordonnees telles que l'unite represente la dimension maximale du plan */ /* de travail du CUBI7. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; DEFV(Fsommet7,DTb1(facette,NOMBRE_DE_SOMMETS_D_UNE_FACETTE_CARREE)); /* Facette courante a afficher sur l'ecran. */ DEFV(Float,INIT(produit_vectoriel,FLOT__UNDEF)); /* Produit vectoriel des deux diagonales pour valider l'ordre des sommets. */ /*..............................................................................................................................*/ Test(IFNE(NOMBRE_DE_SOMMETS_D_UNE_FACETTE_CARREE,EXP2(BI_DIMENSIONNEL))) Bblock PRINT_ERREUR("le format des facettes carrees est mauvais"); Eblock ATes Bblock Eblock ETes Test(IFGT(coordonnee_Z,Zinfini7)) Bblock PRINT_ERREUR("la coordonnee 'Z' argument est mauvaise"); Eblock ATes Bblock Eblock ETes begin_image Bblock Test(IFET(IFLE(SUCX(X),Xmax),IFLE(SUCY(Y),Ymax))) Bblock GENERATION_FACETTE_CARREE(facette,sommet4_1,NEUT(X),NEUT(Y),coordonnee_Z); GENERATION_FACETTE_CARREE(facette,sommet4_2,SUCX(X),NEUT(Y),coordonnee_Z); GENERATION_FACETTE_CARREE(facette,sommet4_3,SUCX(X),SUCY(Y),coordonnee_Z); GENERATION_FACETTE_CARREE(facette,sommet4_4,NEUT(X),SUCY(Y),coordonnee_Z); /* */ /* Y(JFC) ^ */ /* | 4-----3 */ /* | | \ / | */ /* | | / \ | */ /* Y |....1-----2 */ /* | . */ /* |------------------> */ /* X X(JFC) */ /* */ /* a partir du sous-echantillonnage de l'image on reconstitue des facettes */ /* carrees dont le contenu sera calcule par interpolation sur les quatre */ /* sommets. ATTENTION : on n'oubliera pas le fait que les facettes une */ /* fois projetees doivent etre decrites par une liste de sommets allant */ /* dans le sens trigonometrique, or dans 'GENERATION_FACETTE_CARREE' on */ /* fait une symetrie par rapport a l'axe 'OX' puisque l'axe du CUBI7 */ /* descend, donc ici, on cree une liste dans le sens anti-trigonometrique... */ /* Et apres, les mauvaises langues iront dire que le CUBI7 n'est pas une */ /* vraie machine 3D... */ EGAL(produit_vectoriel ,PvectZ(SOUS(ASD1(ITb1(facette,INDX(sommet4_3,PREMIER_SOMMET)),x) ,ASD1(ITb1(facette,INDX(sommet4_1,PREMIER_SOMMET)),x) ) ,SOUS(ASD1(ITb1(facette,INDX(sommet4_3,PREMIER_SOMMET)),y) ,ASD1(ITb1(facette,INDX(sommet4_1,PREMIER_SOMMET)),y) ) ,SOUS(ASD1(ITb1(facette,INDX(sommet4_3,PREMIER_SOMMET)),z) ,ASD1(ITb1(facette,INDX(sommet4_1,PREMIER_SOMMET)),z) ) ,SOUS(ASD1(ITb1(facette,INDX(sommet4_4,PREMIER_SOMMET)),x) ,ASD1(ITb1(facette,INDX(sommet4_2,PREMIER_SOMMET)),x) ) ,SOUS(ASD1(ITb1(facette,INDX(sommet4_4,PREMIER_SOMMET)),y) ,ASD1(ITb1(facette,INDX(sommet4_2,PREMIER_SOMMET)),y) ) ,SOUS(ASD1(ITb1(facette,INDX(sommet4_4,PREMIER_SOMMET)),z) ,ASD1(ITb1(facette,INDX(sommet4_2,PREMIER_SOMMET)),z) ) ) ); /* Calcul du produit vectoriel des deux diagonales 'D13' et 'D24'... */ Test(IZNE(produit_vectoriel)) Bblock /* Ainsi, on ne prend en compte que les facettes non reduites a leur */ /* plus simple expression (cas par exemple des sorties d'ecran...). */ Test(IZGT(produit_vectoriel)) Bblock /* Validation du sens de parcours des sommets d'une facette ; pour ce */ /* faire, on calcule les deux diagonales 'D13' et 'D24' de la facette, */ /* puis leur produit vectoriel, soit : */ /* */ /* | x13 y13 z13 | */ /* | x24 y24 z24 | */ /* | VNx VNy VNz | */ /* */ /* ou (VNx,VNy,VNz) designe le vecteur normal ; la facette (1,2,3,4) est */ /* correctement orientee si la composante en 'Z', soit x13.y24-x24.y13 */ /* est negative (strictement), c'est-a-dire orientee vers l'observateur... */ PRINT_ERREUR("les facettes sont mal orientees"); Eblock ATes Bblock Eblock ETes Test(IL_Y_A_ERREUR(geff(facette ,NOMBRE_DE_SOMMETS_D_UNE_FACETTE_CARREE ) ) ) /* Et transfert de la facette courante. */ Bblock PRINT_ERREUR("probleme lors de l'ecriture d'une facette carree"); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes TEST_ERREUR_CUBI7; Eblock ATes Bblock Eblock ETes Eblock end_image RETU_ERROR; Eblock # undef GENERATION_FACETTE_CARREE EFonctionI /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* E N V O I D ' U N E I M A G E ( R , V , B , Z ) E N M O D E */ /* " F A C E T T E S " D A N S U N E F E N E T R E T R I _ D I M E N S I O N N E L L E */ /* M A I S E N P E R M U T A N T ( X , Y , Z ) E T ( R , V , B ) : */ /* */ /*************************************************************************************************************************************/ BFonctionI # define GENERATION_FACETTE_TRIANGULAIRE(facette,sommet,Sx,Sy,Sz) \ Bblock \ EGAL(ASD1(ITb1(facette,INDX(sommet,PREMIER_SOMMET)),cR) \ ,NIVA(SCAL(COXR(Sx) \ ,dimX \ ,COULEURS \ ) \ ) \ ); \ EGAL(ASD1(ITb1(facette,INDX(sommet,PREMIER_SOMMET)),cV) \ ,NIVA(SCAL(COYR(Sy) \ ,dimY \ ,COULEURS \ ) \ ) \ ); \ EGAL(ASD1(ITb1(facette,INDX(sommet,PREMIER_SOMMET)),cB) \ ,NIVA(SCAL(C7ZR(Sz) \ ,C7ZR(Zinfini7) \ ,COULEURS \ ) \ ) \ ); \ /* Mise en place des composantes (ROUGE,VERTE,BLEUE) du sommet courant */ \ /* de la facette. */ \ INITIALISATION_POINT_3D(ITb1(facette,INDX(sommet,PREMIER_SOMMET)) \ ,TRON(C7XA(ADD2(MUL2(ASI1(taille,dx) \ ,SCAL(NIVR(load_point(image_ROUGE,Sx,Sy)) \ ,COULEURS \ ,dimX \ ) \ ) \ ,_lDENORMALISE_OX7(ASI1(translation,dx)) \ ) \ ) \ ,FLOT(Xmin7) \ ,FLOT(Xmax7_700) \ ) \ ,TRON(C7YA(SOUS(FLOT(Ymax7_576) \ ,ADD2(MUL2(ASI1(taille,dy) \ ,SCAL(NIVR(load_point(image_VERTE,Sx,Sy)) \ ,COULEURS \ ,dimY \ ) \ ) \ ,_lDENORMALISE_OY7(ASI1(translation,dy)) \ ) \ ) \ ) \ ,FLOT(Ymin7) \ ,FLOT(Ymax7_576) \ ) \ ,C7ZA(SCAL(NIVR(load_point(image_BLEUE,Sx,Sy)) \ ,COULEURS \ ,C7ZR(Zinfini7) \ ) \ ) \ ); \ /* Mise en place des coordonnees flottantes (Sx,Sy,Sz) du sommet */ \ /* courant de la facette ; on n'oubliera pas que l'axe 'OY' du */ \ /* CUBI7 est a l'envers... */ \ Eblock \ /* Generation du sommet courant d'une facette flottante. */ DEFV(Common,DEFV(FonctionI,I7funny_3D(image_ROUGE,image_VERTE,image_BLEUE ,coordonnee_Z ,ARGUMENT_POINTERs(translation) ,ARGUMENT_POINTERs(taille) ) ) ) DEFV(Argument,DEFV(image,image_ROUGE)); /* Composante rouge, */ DEFV(Argument,DEFV(image,image_VERTE)); /* Composante verte, */ DEFV(Argument,DEFV(image,image_BLEUE)); /* Composante bleue, */ DEFV(Argument,DEFV(Positive,coordonnee_Z)); /* Coordonnee 'Z' a attribuer a tous les points de la fenetre. */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(translation))); /* Translation a apporter a la fenetre dans la memoire ; celle-ci est */ /* exprimee dans des coordonnees telles que l'unite represente la dimension */ /* maximale du plan de travail du CUBI7. */ DEFV(Argument,DEFV(deltaF_2D,POINTERs(taille))); /* Taille de la fenetre dans la memoire ; celle-ci est exprimee dans des */ /* coordonnees telles que l'unite represente la dimension maximale du plan */ /* de travail du CUBI7. */ /*-----------------------------------------------------------------------------------------------------------------------------------*/ Bblock INIT_ERROR; DEFV(Fsommet7,DTb1(facette,NOMBRE_DE_SOMMETS_D_UNE_FACETTE_TRIANGULAIRE)); /* Facette courante a afficher sur l'ecran ; contrairement a 'fenetre_3D', */ /* on prend ici des facettes triangulaires car en effet, avec des facettes */ /* carrees on obtiendrait souvent des facettes "tordues" (c'est-a-dire */ /* "twistees")... */ DEFV(Float,INIT(produit_vectoriel,FLOT__UNDEF)); /* Produit vectoriel de deux cotes pour valider l'ordre des sommets. */ /*..............................................................................................................................*/ Test(IFGT(coordonnee_Z,Zinfini7)) Bblock PRINT_ERREUR("la coordonnee 'Z' argument est mauvaise"); Eblock ATes Bblock Eblock ETes begin_image Bblock Test(IFET(IFLE(SUCX(X),Xmax),IFLE(SUCY(Y),Ymax))) Bblock GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_1,NEUT(X),NEUT(Y),coordonnee_Z); GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_2,SUCX(X),NEUT(Y),coordonnee_Z); GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_3,SUCX(X),SUCY(Y),coordonnee_Z); /* */ /* Y(JFC) ^ */ /* | 3 */ /* | / | */ /* | / | */ /* Y |....1-----2 */ /* | . */ /* |------------------> */ /* X X(JFC) */ /* */ /* a partir du sous-echantillonnage de l'image on reconstitue des facettes */ /* triangulaires "basses" dont le contenu sera calcule par interpolation sur les */ /* trois sommets. ATTENTION : on n'oubliera pas le fait que les facettes une */ /* fois projetees doivent etre decrites par une liste de sommets allant */ /* dans le sens trigonometrique, or dans 'GENERATION_FACETTE_TRIANGULAIRE' on */ /* fait une symetrie par rapport a l'axe 'OX' puisque l'axe du CUBI7 */ /* descend, donc ici, on cree une liste dans le sens anti-trigonometrique... */ /* Et apres, les mauvaises langues iront dire que le CUBI7 n'est pas une */ /* vraie machine 3D... */ EGAL(produit_vectoriel ,SOUS(MUL2(SOUS(ASD1(ITb1(facette,INDX(sommet3_3,PREMIER_SOMMET)),x) ,ASD1(ITb1(facette,INDX(sommet3_1,PREMIER_SOMMET)),x) ) ,SOUS(ASD1(ITb1(facette,INDX(sommet3_3,PREMIER_SOMMET)),y) ,ASD1(ITb1(facette,INDX(sommet3_2,PREMIER_SOMMET)),y) ) ) ,MUL2(SOUS(ASD1(ITb1(facette,INDX(sommet3_3,PREMIER_SOMMET)),x) ,ASD1(ITb1(facette,INDX(sommet3_2,PREMIER_SOMMET)),x) ) ,SOUS(ASD1(ITb1(facette,INDX(sommet3_3,PREMIER_SOMMET)),y) ,ASD1(ITb1(facette,INDX(sommet3_1,PREMIER_SOMMET)),y) ) ) ) ); /* Calcul du produit vectoriel des deux cotes 'D13' et 'D23'... */ Test(IZNE(produit_vectoriel)) Bblock /* Ainsi, on ne prend en compte que les facettes non reduites a leur */ /* plus simple expression (cas par exemple des sorties d'ecran...). */ Test(IZGT(produit_vectoriel)) Bblock /* Validation du sens de parcours des sommets d'une facette ; pour ce */ /* faire, on calcule les deux cotes 'D13' et 'D23' de la facette, */ /* puis leur produit vectoriel, soit : */ /* */ /* | x13 y13 z13 | */ /* | x23 y23 z23 | */ /* | VNx VNy VNz | */ /* */ /* ou (VNx,VNy,VNz) designe le vecteur normal ; la facette (1,2,3) est */ /* correctement orientee si la composante en 'Z', soit x13.y23-x23.y13 */ /* est negative (strictement), c'est-a-dire orientee vers l'observateur... */ GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_3,NEUT(X),NEUT(Y),coordonnee_Z); GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_2,SUCX(X),NEUT(Y),coordonnee_Z); GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_1,SUCX(X),SUCY(Y),coordonnee_Z); /* Quand les facettes sont mal orientees, on recommence en changeant l'ordre */ /* de parcours... */ Eblock ATes Bblock Eblock ETes Test(IL_Y_A_ERREUR(geff(facette ,NOMBRE_DE_SOMMETS_D_UNE_FACETTE_TRIANGULAIRE ) ) ) /* Et transfert de la facette courante. */ Bblock PRINT_ERREUR("probleme lors de l'ecriture d'une facette triangulaire 'basse'"); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes TEST_ERREUR_CUBI7; GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_1,NEUT(X),NEUT(Y),coordonnee_Z); GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_2,SUCX(X),SUCY(Y),coordonnee_Z); GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_3,NEUT(X),SUCY(Y),coordonnee_Z); /* */ /* Y(JFC) ^ */ /* | 3-----2 */ /* | | / */ /* | | / */ /* | | / */ /* | | / */ /* Y |....1 */ /* | . */ /* |------------------> */ /* X X(JFC) */ /* */ /* a partir du sous-echantillonnage de l'image on reconstitue des facettes */ /* triangulaires "hautes" dont le contenu sera calcule par interpolation sur les */ /* trois sommets. ATTENTION : on n'oubliera pas le fait que les facettes une */ /* fois projetees doivent etre decrites par une liste de sommets allant */ /* dans le sens trigonometrique, or dans 'GENERATION_FACETTE_TRIANGULAIRE' on */ /* fait une symetrie par rapport a l'axe 'OX' puisque l'axe du CUBI7 */ /* descend, donc ici, on cree une liste dans le sens anti-trigonometrique... */ /* Et apres, les mauvaises langues iront dire que le CUBI7 n'est pas une */ /* vraie machine 3D... */ EGAL(produit_vectoriel ,SOUS(MUL2(SOUS(ASD1(ITb1(facette,INDX(sommet3_2,PREMIER_SOMMET)),x) ,ASD1(ITb1(facette,INDX(sommet3_1,PREMIER_SOMMET)),x) ) ,SOUS(ASD1(ITb1(facette,INDX(sommet3_3,PREMIER_SOMMET)),y) ,ASD1(ITb1(facette,INDX(sommet3_1,PREMIER_SOMMET)),y) ) ) ,MUL2(SOUS(ASD1(ITb1(facette,INDX(sommet3_3,PREMIER_SOMMET)),x) ,ASD1(ITb1(facette,INDX(sommet3_1,PREMIER_SOMMET)),x) ) ,SOUS(ASD1(ITb1(facette,INDX(sommet3_2,PREMIER_SOMMET)),y) ,ASD1(ITb1(facette,INDX(sommet3_1,PREMIER_SOMMET)),y) ) ) ) ); /* Calcul du produit vectoriel des deux cotes 'D12' et 'D13'... */ Test(IZNE(produit_vectoriel)) Bblock /* Ainsi, on ne prend en compte que les facettes non reduites a leur */ /* plus simple expression (cas par exemple des sorties d'ecran...). */ Test(IZGT(produit_vectoriel)) Bblock /* Validation du sens de parcours des sommets d'une facette ; pour ce */ /* faire, on calcule les deux cotes 'D12' et 'D13' de la facette, */ /* puis leur produit vectoriel, soit : */ /* */ /* | x12 y12 z12 | */ /* | x13 y13 z13 | */ /* | VNx VNy VNz | */ /* */ /* ou (VNx,VNy,VNz) designe le vecteur normal ; la facette (1,2,3) est */ /* correctement orientee si la composante en 'Z', soit x12.y13-x13.y12 */ /* est negative (strictement), c'est-a-dire orientee vers l'observateur... */ GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_3,NEUT(X),NEUT(Y),coordonnee_Z); GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_2,SUCX(X),SUCY(Y),coordonnee_Z); GENERATION_FACETTE_TRIANGULAIRE(facette,sommet3_1,NEUT(X),SUCY(Y),coordonnee_Z); /* Quand les facettes sont mal orientees, on recommence en changeant l'ordre */ /* de parcours... */ Eblock ATes Bblock Eblock ETes Test(IL_Y_A_ERREUR(geff(facette ,NOMBRE_DE_SOMMETS_D_UNE_FACETTE_TRIANGULAIRE ) ) ) /* Et transfert de la facette courante. */ Bblock PRINT_ERREUR("probleme lors de l'ecriture d'une facette triangulaire 'haute'"); Eblock ATes Bblock Eblock ETes Eblock ATes Bblock Eblock ETes TEST_ERREUR_CUBI7; Eblock ATes Bblock Eblock ETes Eblock end_image RETU_ERROR; Eblock # undef GENERATION_FACETTE_TRIANGULAIRE EFonctionI # undef TEST_ERREUR_CUBI7 #Aifdef __VERSION__COMPILER_LE_GRAPHIQUE_CUBI7 /* Common,DEFV(Fonction,) : la bibliotheque est conditionnelle... */ #Eifdef __VERSION__COMPILER_LE_GRAPHIQUE_CUBI7 /* Common,DEFV(Fonction,) : la bibliotheque est conditionnelle... */ _______________________________________________________________________________________________________________________________________